home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / role / AMDoc_0_9.lha / AMDoc / Builtins.txt next >
Text File  |  1995-01-21  |  168KB  |  3,999 lines

  1. AmigaMUD, Copyright 1995 by Chris Gray
  2.  
  3.  
  4.             The AmigaMUD Builtin Functions
  5.  
  6.  
  7. This file documents all of the builtin functions in the AmigaMUD
  8. system. The functions are listed in alphabetical order. Each is given
  9. with the category it is in, along with its prototype. Each is then
  10. described and, if appropriate, examples are given. More general
  11. discussions can be found in the ProgConcepts.txt file. The "utility"
  12. in the prototypes indicates that the builtin function does not change
  13. the effective user when it is executed. Some builtins have "wizard" in
  14. their prototype, which means they can only be used by full wizards,
  15. and not by apprentices. Also, some functions can only be executed by
  16. SysAdmin, but this is not indicated in their header.
  17.  
  18.  
  19. AAn: output
  20. proc utility AAn(string s1, s2)string
  21.  
  22.     AAn is used to make output look more like proper English. It
  23.     returns a string which is the concatenation of its two string
  24.     arguments, with either " a " or " an " inserted between them,
  25.     depending on whether the first letter of the second string is a
  26.     vowel or not. E.g.
  27.  
  28.     AAn("You do not have", "apple") => "You do not have an apple"
  29.     AAn("You do not have", "tree")    => "You do not have a tree"
  30.     AAn("", "whatzit") => "a whatzit"
  31.  
  32. AbortEffect: effects
  33. proc utility AbortEffect(thing who; int kind, id)void
  34.  
  35.     AbortEffect is used to abort an ongoing effect in a full client.
  36.     'who' is the thing of the client to be affected, or nil to mean
  37.     the active client. 'kind' is the kind of effect to be aborted,
  38.     with values: 0 => sound, 1 => speech, 2 => music. 'id' is the
  39.     identifier of the specific affect to be aborted. This id is
  40.     also given when the effect is started. E.g.
  41.  
  42.     VSpeak(nil, "Hello there!", 777);
  43.     ...
  44.     AbortEffect(nil, EFFECT_SPEECH, 777);
  45.  
  46. ABPrint: output
  47. proc utility ABPrint(thing location, agent1, agent2; string str)void
  48.  
  49.     ABPrint outputs string 'str' to all clients with the given
  50.     location, except those whose things are identified by 'agent1' and
  51.     'agent2'. Either or both of these can be nil to be ignored. The
  52.     standard scenario uses ABPrint during combat, to allow three
  53.     different messages to be given: one to the attacker, one to the
  54.     victim, and one to any onlookers. The last uses ABPrint.
  55.  
  56. AddButton: effects
  57. proc utility AddButton(int x, y, n; string str)void
  58.  
  59.     AddButton is used to add a mouse-button to the graphics window of
  60.     the active client. 'x' and 'y' give the co-ordinates of the top-
  61.     left corner of the button, 'n' gives the identifier of the button,
  62.     and 'str' is the text contents of the button. The length of the
  63.     text determines the width of the button. Buttons are 16 pixels
  64.     high and 16 + 8 * <text-length> pixels wide. Empty buttons can be
  65.     produced by using strings containing only spaces. When the user
  66.     clicks on the button, the identifier, 'n', is sent to the server
  67.     for processing by the character's current "button action". If
  68.     there is already a button with the indicated id, then the new
  69.     button is ignored. E.g.
  70.  
  71.     AddButton(20, 10, BUTTON_ID, "Hit");
  72.  
  73. AddHead: database
  74. proc utility AddHead(<any list> theList;
  75.     <corresponding element type> theElement)void
  76.  
  77.     AddHead is used to add an element to the front of a list. It is a
  78.     generic function in that it works for any type of list. The new
  79.     element is inserted before any existing elements, so it will have
  80.     index 0 in the list. E.g.
  81.  
  82.     private l CreateIntList().
  83.     l[0]. => error
  84.     AddHead(l, 10).
  85.     l[0]. => 10
  86.     l[1]. => error
  87.     AddHead(l, 999).
  88.     l[0]. => 999
  89.     l[1]. => 10
  90.  
  91. AddRegion: effects
  92. proc utility AddRegion(int x1, y1, x2, y2, n)void
  93.  
  94.     AddRegion adds a mouse sensitive rectangular region to the
  95.     graphics window of the active client. The window is not visible,
  96.     but a mouse-click inside of it (that doesn't hit a button or a
  97.     region with lower identifier) will return the identifier of the
  98.     region and the co-ordinates of the click relative to the top-left
  99.     corner of the region. 'x1' and 'y1' are the co-ordinates of the
  100.     top-left corner of the region, and 'x2' and 'y2' are the co-
  101.     ordinates of the bottom-right corner of the region. Point (x2, y2)
  102.     is included in the region. 'n' is the identifier for the region.
  103.     Such a region is used in the standard scenario over the entire
  104.     map-view area of the graphics window. The position of the click
  105.     relative to the position of the player cursor determines which
  106.     direction the user wants to move in. Another region is used for
  107.     the icon editor. Attempting to add a region using an identifier
  108.     that is already in use has no effect. E.g.
  109.  
  110.     AddRegion(10, 10, 90, 150, REGION_ID);
  111.  
  112. AddTail: database
  113. proc utility AddTail(<any list> theList;
  114.     <corresponding element type> theElement)void
  115.  
  116.     AddTail adds the indicated element to the end of the list. It is
  117.     generic, in that it will work on any type of list. See also:
  118.     'AddHead'. E.g.
  119.  
  120.     private l CreateIntList().
  121.     l[0]. => error
  122.     AddTail(l, 10).
  123.     l[0] => 10
  124.     l[1] => error
  125.     AddTail(l, 999).
  126.     l[0] => 10
  127.     l[1] => 999
  128.  
  129. After: machine/character
  130. proc utility After(int seconds; action theAction)void
  131.  
  132.     After is the heart of automatic activities in AmigaMUD. It
  133.     arranges things so that after 'seconds' seconds, function
  134.     'theAction' is called (with no parameters). The function must be
  135.     one which returns no result (void). When the function is called,
  136.     the active agent will be either the character who was active when
  137.     After was called, or the machine which was active when After was
  138.     called. Note that all such scheduled actions are cancelled when
  139.     the server is shut down - they are not automatically re-installed
  140.     when the server is restarted. Characters and machines have
  141.     activation actions, which are called when the server restarts,
  142.     which can be used to restart any 'After' actions. Any machine
  143.     which does things independently of players will normally have one
  144.     or more 'After' activities. Continuous scheduling of actions can
  145.     be done by using After as the last thing done in a function called
  146.     by After. E.g.
  147.  
  148.     private proc machineStep()void:
  149.         /* Do things based on the machine's state and what is
  150.            happening around it. */
  151.         ...
  152.         After(30 + Random(30), machineStep);
  153.     corp;
  154.  
  155. AgentLocation: machine/character
  156. proc utility AgentLocation(thing theAgent)thing
  157.  
  158.     AgentLocation returns the thing which is the current location of
  159.     the agent whose thing is passed as 'theAgent'. 'theAgent' can be
  160.     the thing of a player character or of a machine. Note that it is
  161.     possible for an agent to be nowhere, so that AgentLocation returns
  162.     nil. Builtin "Here()" is similar to "AgentLocation(Me())". If a
  163.     player character thing is passed, and that character is not
  164.     currently connected, AgentLocation will return nil.
  165.  
  166. APrint: output
  167. proc utility APrint(string message)void
  168.  
  169.     APrint is the AmigaMUD broadcast facility. It sends the given
  170.     'message' to all active clients on the MUD. It is useful for use
  171.     by SysAdmin to make announcements, like "system going down in five
  172.     minutes". The standard scenario uses it to announce when a
  173.     character solves a quest. Note that the server flushes output to
  174.     any given client before it starts output to another client. Thus,
  175.     any messages printed using "APrint" should be done all at once,
  176.     otherwise unwanted newlines may appear.
  177.  
  178. BootClient: machine/character
  179. proc utility BootClient(character who)void
  180.  
  181.     BootClient can be used to force a player off of the system. It is
  182.     equivalent to code running for the player executing "Quit()". The
  183.     client will be shutdown when it is next non-active (which is
  184.     normally immediately). Note that BootClient allows the character
  185.     to execute any shutdown code. BootClient is a graceful boot. If
  186.     something is wrong (e.g. the shutdown code causes troubles), the
  187.     more forceful 'NukeClient' can be used. NukeClient will often mess
  188.     up the character, however.
  189.  
  190. CallEffect: effects
  191. proc utility CallEffect(thing who; int whichEffect)void
  192.  
  193.     CallEffect is used to execute an effect which has been defined
  194.     for the client 'who'. Effects are identified by an identifier
  195.     given when the effect is created using 'DefineEffect' and
  196.     'EndEffect'. If the identified effect is not known to the remote
  197.     client (the "MUD" program), then nothing is done. CallEffect
  198.     can be used inside an effect being defined, in which case it is
  199.     like an effect subroutine call. E.g.
  200.  
  201.     DefineEffect(nil, EFFECT_ID);
  202.     ...
  203.     /* graphics, sound, etc. effect calls */
  204.     ...
  205.     CallEffect(nil, SUBROUTINE_EFFECT_ID);
  206.     ...
  207.     EndEffect();
  208.     ...
  209.     CallEffect(nil, EFFECT_ID);
  210.  
  211. CanEdit: machine/character
  212. proc utility CanEdit()bool
  213.  
  214.     CanEdit returns an indication of whether or not the active agent
  215.     can edit functions and strings. Thus, the scenario can use
  216.     'EditString' to allow editing of a description, or can use line-
  217.     by-line input to read it. In general, a player using "MUD" can
  218.     edit, as can a local player using "SMUD", and all others cannot.
  219.  
  220. Capitalize: utility
  221. proc utility Capitalize(string str)string
  222.  
  223.     Capitalize returns its string argument 'str', but with its first
  224.     character capitalized (made upper-case) if it is a letter. E.g.
  225.  
  226.     Capitalize("hello") => "Hello"
  227.     Capitalize("123") => "123"
  228.  
  229. ChangeName: machine/character
  230. proc utility wizard ChangeName(string newName)void
  231.  
  232.     ChangeName allows the active character to change his/her name.
  233.     Just assigning to property "p_pName" does not work, and will
  234.     result in an inconsistent character. Valid names must be non-
  235.     empty, must not contain any punctuation, must be no more than 20
  236.     characters long, and must not match any existing character name.
  237.  
  238. Character: machine/character
  239. proc utility Character(string name)character
  240.  
  241.     Character looks up the passed 'name' in the 'Characters' table,
  242.     returning nil or the named character. The character does not have
  243.     to be connected. Note that the value returned is of type character
  244.     and not of type thing - use 'CharacterThing' to return the thing
  245.     for the character.
  246.  
  247. CharacterLocation: machine/character
  248. proc utility CharacterLocation(character theCharacter)thing
  249.  
  250.     CharacterLocation is similar to AgentLocation, in that it returns
  251.     the thing which is the location of the 'theCharacter'. Only
  252.     character values can be passed, however, and the character's
  253.     location is returned even if the character is not currently
  254.     connected to the MUD.
  255.  
  256. CharacterTable:  machine/character
  257. proc utility CharacterTable(character theCharacter)table
  258.  
  259.     CharacterTable returns the table which is the private table of
  260.     'theCharacter'. All player characters have such a table.
  261.  
  262. CharacterThing: machine/character
  263. proc utility CharacterThing(character theCharacter)thing
  264.  
  265.     CharacterThing returns the thing associated with player character
  266.     'theCharacter'. All characters have such a thing. The reverse
  267.     action is performated by 'ThingCharacter'.
  268.  
  269. ClearButtons: effects
  270. proc utility ClearButtons()void
  271.  
  272.     ClearButtons removes all buttons from the active client's display,
  273.     and also removes the corresponding data structures. This is used
  274.     when a new set of buttons is to be drawn. When the buttons are
  275.     removed, the spaces they occupied are filled in with colour 0.
  276.  
  277. ClearRegions: effects
  278. proc utility ClearRegions()void
  279.  
  280.     ClearRegions removes all mouse-hit regions from the active client.
  281.     Since such regions are not visible, this operation is not visible.
  282.  
  283. ClearThing: database
  284. proc utility ClearThing(thing theThing)void
  285.  
  286.     ClearThing removes all properties from the passed thing. Even
  287.     properties which cannot normally be changed by the effective user
  288.     are removed. The use-counts on the properties themselves and on
  289.     their values (if appropriate) are decremented appropriately. If
  290.     the thing has a usecount of 0, it will be released, and the space
  291.     it occupied in the database will be available for reuse.
  292.     Similarly, any properties or values whose usecounts become 0 will
  293.     also be freed. ClearThing is normally used for operations like
  294.     destroying objects and rooms. Note that a local variable (or
  295.     function parameter) pointing to a thing does not consititute a
  296.     formal use of that that thing, so that variable becomes invalid if
  297.     there are no uses of the thing and it is ClearThing'd. E.g.
  298.  
  299.     th := CreateThing(nil); /* thing has no uses yet! */
  300.     ClearThing(th);     /* thing is now gone! th is invalid */
  301.     th@prop := 6;        /* this can crash the system! */
  302.  
  303. ClientsActive: utility
  304. proc utility ClientsActive()bool
  305.  
  306.     ClientsActive returns 'true' if there are currently any player
  307.     characters active in the MUD, and 'false' otherwise. It is useful
  308.     in the step functions of machines to determine whether or not they
  309.     should be normally active or should go quiescent for a while.
  310.     Well-behaved machines go mostly quiescent when there are no active
  311.     clients, to minimize the load that the AmigaMUD server puts on the
  312.     system when there are no players. E.g.
  313.  
  314.     define tp_myMachine proc machineStep()void:
  315.  
  316.         doLotsOfNeatThings();
  317.         if ClientsActive() then
  318.         After(10 + Random(10), machineStep);
  319.         else
  320.         After(100, machineStep);
  321.         fi;
  322.     corp;
  323.  
  324. ClientVersion: machine/character
  325. proc utility ClientVersion(thing who)int
  326.  
  327.     ClientVersion returns the version number of the indicated client
  328.     program. This allows scenarios to do different actions depending
  329.     on that version. E.g. if newer versions of the clients offer more
  330.     capabilities, then they can be used, and older versions can use
  331.     older capabilities. The version number is the integral part of the
  332.     displayed version number times ten plus the decimal part. E.g. for
  333.     release V0.6 ClientVersion returns 6. Unfortunately, this builtin
  334.     returned an incorrect value in version 0.5. Also unfortunately,
  335.     the version released as V0.7 still contained internal version
  336.     numbers of 0.6 . E.g.
  337.  
  338.     if ClientVersion(nil) >= 20 then
  339.         doFancyNewSuperNeatEffect(nil);
  340.     else
  341.         doGrungyOldUglyEffect(nil);
  342.     fi;
  343.  
  344. Count: utility
  345. proc utility Count(<any list> theList)int
  346.  
  347.     Count is a generic function, accepting any type of list. It
  348.     returns the count of the number of elements in that list. E.g.
  349.  
  350.     for i from 0 upto Count(theList) - 1 do
  351.         doSomethingWith(theList[i]);
  352.     od;
  353.  
  354. CreateActionList: database
  355. proc utility CreateActionList()list action
  356.  
  357.     CreateActionList returns a new, empty list of actions.
  358.  
  359. CreateActionListProp: database
  360. proc utility CreateActionListProp()property list action
  361.  
  362.     CreateActionListProp returns a new property which can be used to
  363.     attach a list of actions to a thing. The new property has no name,
  364.     so it should be put into a table to give it one. E.g.
  365.  
  366.     define myTable myNewProp CreateActionListProp().
  367.     myTestThing@myNewProp := CreateActionList().
  368.     AddTail(myTestThing@myNewProp, myNeatFunction).
  369.  
  370. CreateActionProp: database
  371. proc utility CreateActionProp()property action
  372.  
  373.     CreateActionProp returns a new property which can be used to
  374.     attach a single action to a thing. The new property has no name,
  375.     so it should be put into a table to give it one. E.g.
  376.  
  377.     define myTable myNewProp CreateActionProp().
  378.     myTestThing@myNewProp := myNeatFunction.
  379.  
  380. CreateBoolProp: database
  381. proc utility CreateBoolProp()property bool
  382.  
  383.     CreateBoolProp returns a new property which can be used to attach
  384.     a bool flag to a thing. The new property has no name, so it should
  385.     be put into a table to give it one. E.g.
  386.  
  387.     define myTable myNewProp CreateBoolProp().
  388.     myTestThing@myNewProp := true.
  389.  
  390. CreateCharacter: machine/character
  391. proc utility CreateCharacter(string name, password)void
  392.  
  393.     CreateCharacter creates a new character. The other way that
  394.     characters can be created is by players themselves when they are
  395.     connecting to the system. The latter requires that they know the
  396.     creation password (if one is set) and that the creation password
  397.     not start with an asterisk ("*"). If the system administrator
  398.     decides to disallow such character creations, then all characters
  399.     must be explicitly created using CreateCharacter. 'name' is the
  400.     desired name of the new character, and as usual, must not contain
  401.     any spaces or punctuation characters. 'password' is the initial
  402.     password for the character - the player can change it later. E.g.
  403.  
  404.     CreateCharacter("Fred_Smith", "xyzzy").
  405.  
  406. CreateGrammar: parsing
  407. proc utility CreateGrammar()grammar
  408.  
  409.     CreateGrammar returns a new, empty grammar. A grammar in AmigaMUD
  410.     is a type of table used to hold command words, and the information
  411.     on how to handle those words. Grammars separate from the main
  412.     grammar are useful for implementing "subcommands" like the build
  413.     commands, and for implementing sets of special commands for use in
  414.     special locations or on special occasions.
  415.  
  416. CreateGrammarProp: database
  417. proc utility CreateGrammarProp()property grammar
  418.  
  419.     CreateGrammarProp returns a new property which can be used to
  420.     attach a grammar to a thing. The new property has no name, so it
  421.     should be put into a table to give it one. E.g.
  422.  
  423.     define myTable myNewProp CreateGrammarProp().
  424.     myTestThing@myNewProp := CreateGrammar().
  425.     VerbTail(myTestThing@myNewProp, "spelunk", doSpelunk).
  426.  
  427. CreateIntArray: database
  428. proc utility CreateIntArray(int size)list int
  429.  
  430.     CreateIntArray returns and fills in a new list of integers. Unlike
  431.     'CreateIntList', the list returned by CreateIntArray is not empty.
  432.     It has space for 'size' elements, and those elements are all
  433.     initialized to 0. This routine is a convenient way to initialize
  434.     such things as icons and mapping tables for coordinate based
  435.     areas. E.g.
  436.  
  437.     list int li;
  438.  
  439.     li := CreateIntArray(10);
  440.     li[5] := 7;
  441.  
  442. CreateIntList: database
  443. proc utility CreateIntList()list int
  444.  
  445.     CreateIntList returns a new, empty list of integers.
  446.  
  447. CreateIntListProp: database
  448. proc utility CreateIntListProp()property list int
  449.  
  450.     CreateIntListProp returns a new property which can be used to
  451.     attach a list of ints to a thing. The new property has no name,
  452.     so it should be put into a table to give it one. E.g.
  453.  
  454.     define myTable myNewProp CreateIntListProp().
  455.     myTestThing@myNewProp := CreateIntList().
  456.     AddTail(myTestThing@myNewProp, 27).
  457.  
  458. CreateIntProp: database
  459. proc utility CreateIntProp()property int
  460.  
  461.     CreateIntProp returns a new property which can be used to attach
  462.     an int to a thing. The new property has no name, so it should be
  463.     put into a table to give it one. E.g.
  464.  
  465.     define myTable myNewProp CreateIntProp().
  466.     myTestThing@myNewProp := 145.
  467.  
  468. CreateMachine: machine/character
  469. proc utility CreateMachine(string name; thing theThing, location;
  470.     action startup)void
  471.  
  472.     CreateMachine is used to create a new machine. Machines are used
  473.     in AmigaMUD to perform actions independent of any players. Each
  474.     machine has a corresponding thing, just like players do. The name
  475.     of a machine can be similar to a player's name, like "Packrat", or
  476.     it can be more like an object's name, like "rat;big,hairy".
  477.     Machines can also have empty names, in which case they will not
  478.     show up in rooms, unless 'ForEachAgent' is used to scan agents.
  479.     'theThing' is the thing which holds all of the machine's
  480.     properties. 'location' is the initial location for the machine; it
  481.     can be nil. 'startup' is an action, having no parameters and no
  482.     result, which will be called when the machine has been created.
  483.     It is normally used to start up any "step" routine which the
  484.     machine uses to perform periodic action. 'startup' can be nil.
  485.     E.g.
  486.  
  487.     private tp_witches CreateTable().
  488.     use tp_witches
  489.     define tp_witches witchSpell CreateActionProp().
  490.     define tp_witches witchCharacter CreateIntProp().
  491.     define tp_witches WC_GOOD 0.
  492.     define tp_witches WC_NEUTRAL 1.
  493.     define tp_witches WC_EVIL 2.
  494.     define tp_witches proc spellTurnNosePurple(thing who)void:
  495.         /* turn somebody's nose purple */
  496.     corp;
  497.     define tp_witches proc witchStep()void:
  498.         /* various and sundry nasty stuff */
  499.         After(10, witchStep);
  500.     corp;
  501.     define tp_witches proc witchInit()void:
  502.         After(10, witchStep);
  503.     corp;
  504.     define tp_witches proc createWitch()void:
  505.         thing theWitch;
  506.  
  507.         theWitch := CreateThing(modelWitch);
  508.         theWitch@witchSpell := spellTurnNosePurple;
  509.         theWitch@witchCharacter := WC_EVIL;
  510.         CreateMachine("Crondik;Witch", theWitch, r_blackPit,
  511.               witchInit);
  512.     corp;
  513.  
  514. CreateStringProp: database
  515. proc utility CreateStringProp()property string
  516.  
  517.     CreateStringProp returns a new property which can be used to
  518.     attach a string to a thing. The new property has no name, so it
  519.     should be put into a table to give it one. E.g.
  520.  
  521.     define myTable myNewProp CreateStringProp().
  522.     myTestThing@myNewProp := "hello there world".
  523.  
  524. CreateTable: database
  525. proc utility CreateTable()table
  526.  
  527.     CreateTable returns a new empty table. The table can be used to
  528.     store symbols. Separate tables are used so that the number of
  529.     symbols in your private table (or the public one) does not get too
  530.     large. Having too many symbols in a single table can cause
  531.     problems for the database cache, uses a lot of memory, and is hard
  532.     to handle for the user. The source files for the standard scenario
  533.     create quite a few new tables, usually one or more per major
  534.     source file. The symbols defined in that source file that are not
  535.     needed outside of that source file are put into that table. See
  536.     the example given with 'CreateMachine' for an example of using
  537.     such a table.
  538.  
  539. CreateTableProp: database
  540. proc utility CreateTableProp()property table
  541.  
  542.     CreateTableProp returns a new property which can be used to attach
  543.     a table to a thing. The new property has no name, so it should be
  544.     put into a table to give it one. E.g.
  545.  
  546.     define myTable myNewProp CreateTableProp().
  547.     myTestThing@myNewProp := CreateTable().
  548.  
  549. CreateThing: database
  550. proc utility CreateThing(thing parent)thing
  551.  
  552.     CreateThing returns a new thing in the database. The new thing's
  553.     parent is set to 'parent', which can be nil. CreateThing is used
  554.     to create nearly all items that a player will interact with in
  555.     AmigaMUD: rooms, objects, monsters, etc. A newly created thing has
  556.     no properties other than any inherited from its parent (and its
  557.     parent's parent, etc.)
  558.  
  559. CreateThingList: database
  560. proc utility CreateThingList()list thing
  561.  
  562.     CreateThingList returns a new, empty list of things.
  563.  
  564. CreateThingListProp: database
  565. proc utility CreateThingListProp()property list thing
  566.  
  567.     CreateThingListProp returns a new property which can be used to
  568.     attach a list of things to a thing. The new property has no name,
  569.     so it should be put into a table to give it one. E.g.
  570.  
  571.     define myTable myNewProp CreateThingListProp().
  572.     myTestThing@myNewProp := CreateThingList().
  573.     AddTail(myTestThing@myNewProp, myOtherTestThing).
  574.  
  575. CreateThingProp: database
  576. proc utility CreateThingProp()property thing
  577.  
  578.     CreateThingProp returns a new property which can be used to attach
  579.     a thing to another thing. The new property has no name, so it
  580.     should be put into a table to give it one. This kind of property
  581.     is used, for example, to point from one room to another, to
  582.     indicate a connection between the rooms. E.g.
  583.  
  584.     define myTable myNewProp CreateThingProp().
  585.     myTestThing@myNewProp := myOtherThing.
  586.  
  587. Date: utility
  588. proc utility Date()string
  589.  
  590.     Date returns a string containing the current time and date. E.g.
  591.  
  592.     Date() => "Sat Jun 11 16:49:14 1994"
  593.  
  594. DateShort: utility
  595. proc utility DateShort()string
  596.  
  597.     Date returns a string containing the current time and date. The
  598.     form returned is in a shorter form than that returned by 'Date',
  599.     and is sortable.
  600.  
  601.     DateShort() => "94/06/11 16:49:17"
  602.  
  603. DefineAction: symbols
  604. proc utility DefineAction(table theTable; string name;
  605.     action theAction)bool
  606.  
  607.     DefineAction adds an entry to the 'theTable', with name 'name'
  608.     which is a new name for the passed action 'theAction'. This
  609.     routine is mainly of use in the builder code. The value returned
  610.     is 'true' if the definition was successful, else 'false'.
  611.  
  612. DefineCounter: symbols
  613. proc utility DefineCounter(table theTable; string name;
  614.     property int theCounter)bool
  615.  
  616.     DefineCounter adds a new int property symbol to the indicated
  617.     table. It is mainly used in the builder code. DefineCounter
  618.     returns 'true' if the definition succeeded.
  619.  
  620. DefineEffect: effects
  621. proc utility DefineEffect(thing who; int whichEffect)void
  622.  
  623.     DefineEffect starts the definition of a new effect for the client
  624.     indicated by 'who'. 'whichEffect' is an identifier for the new
  625.     effect; it must be different for each effect defined. Defining an
  626.     affect sends the "code" for the effect to the client, and the
  627.     client adds that effect code to its effect cache. From then on,
  628.     unless that effect is flushed from the effect cache, the effect
  629.     can be called in that client by simply sending a CallEffect
  630.     request. An effect can be an entire global effect, such as the
  631.     standard scenario's view of the streets scene, or can be an
  632.     "effects subroutine" such as one for a horizontal door. The
  633.     scenario can test whether or not a client has a copy of an effect
  634.     with a given id using the 'KnowsEffect' builtin. For example, here
  635.     is the code in the standard scenario for displaying one of the
  636.     locations in the Squirrel quest area:
  637.  
  638.     if not KnowsEffect(nil, SQ_VALLEY13_ID) then
  639.         DefineEffect(nil, SQ_VALLEY13_ID);
  640.         GSetImage(nil, "sq_valley13");
  641.         IfFound(nil);
  642.         GShowImage(nil, "", 0, 0, 160, 100, 0, 0);
  643.         Else(nil);
  644.         AutoOpenSpace();
  645.         GSetPen(nil, C_FOREST_GREEN);
  646.         GAMove(nil, 80, 50);
  647.         GEllipse(nil, 70, 40, true);
  648.         Fi(nil);
  649.         EndEffect();
  650.     fi;
  651.     CallEffect(nil, SQ_VALLEY13_ID);
  652.  
  653.     If the current client (nil) does not know the effect indicated by
  654.     int constant "SQ_VALLEY13_ID", then the definition of that effect
  655.     is sent to the client. After that definition, if needed, the
  656.     effect is called to display the image. Inside the effect, the
  657.     client program is asked to look for an image called "sq_valley13".
  658.     If that image is found, then it is displayed, and the effect is
  659.     complete. If the image is not found, then an approximation of the
  660.     image is drawn using the "AutoOpenSpace" autographics routine, and
  661.     adding a green ellipse to it, representing the oak tree.
  662.  
  663. DefineFlag: symbols
  664. proc utility DefineFlag(table theTable; string name;
  665.     property bool theFlag)bool
  666.  
  667.     DefineFlag adds a new bool property symbol to the indicated
  668.     table. It is mainly used in the builder code. DefineFlag returns
  669.     true if the definition succeeded.
  670.  
  671. DefineString: symbols
  672. proc utility DefineString(table theTable; string name;
  673.     property string theString)bool
  674.  
  675.     DefineString adds a new string property symbol to the indicated
  676.     table. It is mainly used in the builder code. DefineString returns
  677.     true if the definition succeeded.
  678.  
  679. DefineTable: symbols
  680. proc utility DefineTable(table theTable; string name; table newTable)bool
  681.  
  682.     DefineTable adds a reference to a table, 'newTable', to another
  683.     table, 'theTable', with name 'name'. Thus, 'theTable' now contains
  684.     'newTable' as one of its entries. This function is mostly used by
  685.     the builder code.
  686.  
  687. DefineThing: symbols
  688. proc utility DefineThing(table theTable; string name; thing theThing)bool
  689.  
  690.     DefineThing adds a reference to a thing, 'theThing', to a table,
  691.     'theTable', with name 'name'. Thus, 'theTable' now contains
  692.     'theThing' as one of its entries. This function is mostly used by
  693.     the builder code.
  694.  
  695. DelElement: database
  696. proc utility DelElement(<any list> theList;
  697.     <corresponding element type> valu)void
  698.  
  699.     DelElement is used to delete an element from a list. It is a
  700.     generic function in that it works for any kind of list. 'valu',
  701.     the element to be deleted, must be of the corresponding type. It
  702.     is not an error if the element is not found in the list. If the
  703.     list contains more than one occurrence of the element, only the
  704.     first one (the one with the lowest index) is deleted. E.g.
  705.  
  706.     private th CreateThing(nil).
  707.     private listIntProp CreateIntListProp().
  708.     th@listIntProp := CreateIntArray(5).
  709.     th@listIntProp[0] := 7.
  710.     th@listIntProp[4] := 7.
  711.     th@listIntProp.
  712.     ==> {7, 0, 0, 0, 7}
  713.     DelElement(th@listInt, 7).
  714.     th@listIntProp.
  715.     ==> {0, 0, 0, 7}
  716.     DelElement(th@listInt, 7).
  717.     th@listIntProp.
  718.     ==> {0, 0, 0}
  719.  
  720. DeleteSymbol: symbols
  721. proc utility DeleteSymbol(table theTable; string name)bool
  722.  
  723.     DeleteSymbol attempts to delete symbol 'name' from table
  724.     'theTable'. If it can, it does so and returns 'true', otherwise
  725.     it returns 'false'. If it fails to delete the symbol, an error
  726.     comment will have been printed to the active client.
  727.  
  728. DeleteWord: parsing
  729. proc utility DeleteWord(grammar theGrammar; string theWord)void
  730.  
  731.     DeleteWord deletes word 'theWord' from grammar 'theGrammar'. It is
  732.     an error to try to delete a word that is not in the grammar, or if
  733.     you do not own the grammar. Also, if the word has any existing
  734.     synonyms, it cannot be deleted - those synonyms must be deleted
  735.     first.
  736.  
  737. DescribeKey: database
  738. proc utility DescribeKey(int key)void
  739.  
  740.     DescribeKey considers the int argument passed to it to be a valid
  741.     AmigaMUD internal key, and attempts to describe the value of that
  742.     key. This function can be run ONLY by SysAdmin, since it is
  743.     potentially dangerous. SysAdmin should be careful to only use key
  744.     values that are known to be valid, since invalid keys can result
  745.     in aborts in the database code. Keys are usually expressed as
  746.     hexadecimal int constants for this purpose.
  747.  
  748. DescribeSymbol: symbols
  749. proc utility DescribeSymbol(table theTable; string name)void
  750.  
  751.     DescribeSymbol will print out a description of the value of symbol
  752.     'name' in table 'theTable', provided that that symbol is in the
  753.     table. This is very similar to the "describe" wizard-mode command,
  754.     except that only one specific table is searched for the key. This
  755.     function is used to implement the "@describe" builder command.
  756.  
  757. DestroyCharacter: machine/character
  758. proc utility DestroyCharacter(string theCharacter)void
  759.  
  760.     DestroyCharacter is used to remove an unwanted player character
  761.     from the database. If the character is currently connected, they
  762.     will be disconnected (as in 'BootClient') and the destruction will
  763.     happen after the connection is gone. This function deletes the
  764.     character data structure, the corresponding thing, and all
  765.     properties of that thing. It cannot undo all that the character
  766.     may have done to the system, such as creating rooms and objects,
  767.     killing off monsters or other players, etc. Only SysAdmin, or code
  768.     that SysAdmin writes, can use DestroyCharacter. E.g.
  769.  
  770.     DestroyCharacter("Bad_Boy").
  771.  
  772. DestroyMachine: machine/character
  773. proc utility DestroyMachine(thing machine)void
  774.  
  775.     DestroyMachine is used to destroy a machine that is no longer
  776.     needed. For example, in the standard scenario DestroyMachine is
  777.     used to destroy monsters in the Proving Grounds that are killed.
  778.     The thing of the specific machine to be destroyed is passed. If
  779.     there is still a reference to the machine's thing when this
  780.     function is called, the machine data structure and all properties
  781.     of the thing are deleted, but the thing itself will stay until all
  782.     references to it are gone.
  783.  
  784. DumpThing: utility
  785. proc utility DumpThing(thing key)void
  786.  
  787.     DumpThing can only be executed by SysAdmin, directly at the
  788.     wizard-mode prompt. It symbolically dumps out everything about the
  789.     passed thing. It does not matter what tables the needed symbols
  790.     are in - they will be found. This operation can be quite
  791.     expensive, in that it may have to access all of the tables in the
  792.     system. The operation could also crash the server if not enough
  793.     cache space or memory is available. This is why the function is so
  794.     restricted. The symbols are printed as "paths" if they are not in
  795.     the public symbol table. A path starts with the name of the player
  796.     who owns the table, followed by possibly more table names, and
  797.     finally a symbol, all separated by slashes. If a private symbol
  798.     table itself is printed, then it is printed as the name of the
  799.     character followed by "/PRIVATE". All of these paths are enclosed
  800.     in angle brackets ("<" and ">") to distinguish them from normal
  801.     symbolic output. Here is some example output:
  802.  
  803. > DumpThing(Parent(Me()@p_pWeapon)).
  804. <THING:08000953>: thing, parent <NIL-THING>, owner SysAdmin, useCount 2,
  805.     propCount 8, ts_readonly:
  806.   <p_oName>: "Thor;Hammer,of.hammer"
  807.   <t_base/p_oDesc>:
  808. "The Hammer of Thor appears to be a special weapon. It smashes instead of "
  809. "slashes, but that is likely to be just as effective. It appears to be quite "
  810. "heavy and unwieldy, but you seem to have no trouble with it."
  811.   <t_base/p_oPrice>: 1000000
  812.   <t_base/p_oHome>: <SysAdmin/tp_misc/r_lostAndFound>
  813.   <t_fight/p_oStrBonus>: 3
  814.   <t_fight/p_oAccuracy>: 10
  815.   <t_fight/p_oDamage>: 15
  816.   <t_fight/p_oWieldAction>: <SysAdmin/tp_fight/weaponWield>
  817.  
  818. Editing: utility
  819. proc utility Editing()bool
  820.  
  821.     Editing returns 'true' if the active client is currently using an
  822.     editor within the AmigaMUD system. This happens when the user
  823.     edits a string or a function. Editing a string can be triggered by
  824.     the scenario code calling 'EditString', or by a wizard or
  825.     apprentice calling it directly. Editing a function can be
  826.     triggered by the "edit" wizard-mode command or by using the
  827.     'EditProc' builtin. Editing is useful to prevent attempts to start
  828.     a second edit when one is already in progress.
  829.  
  830. EditProc: utility
  831. proc utility EditProc(action theProc)void
  832.  
  833.     EditProc is a way for executing AmigaMUD code to trigger editing
  834.     of an AmigaMUD function. This has the same effect as a user in
  835.     wizard mode using the "edit" command.
  836.  
  837. EditString: utility
  838. proc utility EditString(string str; action handler; bool raw;
  839.     string prompt)void
  840.  
  841.     EditString throws the active client into an editor (either the
  842.     internal one or an external one), editing the string given by
  843.     'str'. 'handler' must be supplied, and must be a function of type:
  844.  
  845.     proc editHandler(string newString; bool success)void
  846.  
  847.     'prompt' is the string that will appear in the message bar at the
  848.     bottom of the editing window in the internal editor. If 'raw' is
  849.     'true', then when the string is read back from the edit session,
  850.     any newlines in the string are copied directly, as are any
  851.     occurences of '\'. If 'raw' is false, then any newlines in the
  852.     string are converted to spaces, if not following another space (in
  853.     the latter case they are just discarded), and any '\' escape
  854.     sequences are replaced by the character they represent. When this
  855.     is all done, the resulting string is passed to the 'handler'
  856.     function, along with a flag saying whether or not the edit was
  857.     successful. The edit can fail if the user aborts out of the
  858.     builtin editor, or if the AmigaMUD system has any problem starting
  859.     an external editor. Also, if the builtin editor fails to allocate
  860.     memory to hold the string, the edit will fail. So, if the handler
  861.     is called with 'success' 'false', it should not modify anything.
  862.     The standard scenario sets 'raw' to true for news articles and
  863.     usenet mail, and sets it to 'false' for everything else (in-MUD
  864.     mail, descriptions, etc.). All of this is done by the
  865.     "GetDocument" function defined in "util.m".
  866.  
  867. Else: effects
  868. proc utility Else(thing who)void
  869.  
  870.     Else is used in effects routines to switch to an alternative.
  871.     The Else is executed at effect generation time, in the remote
  872.     client program, not at any time in the server. Currently, the only
  873.     condition that it can work with is that set up by 'IfFound', which
  874.     tests for the success of one of: GLoadBackGround, GSetImage,
  875.     GShowImage with a name included, GShowBrush, SPlaySound or
  876.     MPlaySong.
  877.  
  878. EndEffect: effects
  879. proc utility EndEffect()void
  880.  
  881.     EndEffect marks the end of an effect definition. See the
  882.     description of DefineEffect for an example.
  883.  
  884. EraseButton: effects
  885. proc utility EraseButton(int n)void
  886.  
  887.     EraseButton removes and erases the mouse button identified by 'n'
  888.     from the display of the active client.
  889.  
  890. EraseRegion: effects
  891. proc utility EraseRegion(int n)void
  892.  
  893.     EraseRegion removes the mouse-select region identified by 'n' from
  894.     the records of the active client.
  895.  
  896. Execute: utility
  897. proc utility Execute(string command)void
  898.  
  899.     Execute attempts to execute the passed 'command' as an AmigaOS
  900.     shell command line. The command is executed on the server machine.
  901.     Only SysAdmin, or a function written by SysAdmin, can use this
  902.     function. SysAdmin is warned to never write a function that allows
  903.     any users to execute an arbitrary command. Technically, the call
  904.     to AmigaOS used is:
  905.  
  906.     nilHandle := Open("nil:", MODE_READWRITE);
  907.     Execute(command, 0, nilHandle);
  908.  
  909.     The sample scenario sources use Execute to call on the UUCP
  910.     programs to post usenet mail and news.
  911.  
  912. FailText: effects
  913. proc utility FailText(thing who; string message)void
  914.  
  915.     FailText can be used in a scenario to indicate to the remote user
  916.     which file, requested as part of an effect, could not be opened.
  917.     The standard scenario uses it to print "The birds sing." if the
  918.     sound file "AmigaMUD:Sounds/birds" cannot be opened when needed.
  919.     The failure message, preceeded by the path to the file, is printed
  920.     in the text window of the client. E.g.
  921.  
  922.     define tp_proving0 proc birdsSingOnce(thing client)void:
  923.         if SOn(client) then
  924.         SPlaySound(client, "birds", BIRDS_SING_ID);
  925.         IfFound(client);
  926.         Else(client);
  927.             FailText(client, "The birds sing.");
  928.         Fi(client);
  929.         else
  930.         SPrint(client, "The birds sing.\n");
  931.         fi;
  932.     corp;
  933.  
  934.     Note that this code only tries to find and play the file if the
  935.     client has Sound enabled.
  936.  
  937. Fi: effects
  938. proc utility Fi(thing who)void
  939.  
  940.     Fi is used to end a condition inside an effect. See the
  941.     description of IfFound for more details.
  942.  
  943. FileClose: utility
  944. proc utility FileClose(int fileId)void
  945.  
  946.     FileClose closes the indicated file. Any buffered output data is
  947.     written to the real file. The file indicated by 'fileId' is no
  948.     longer valid for 'FileRead'/'FileWrite' operations. Only SysAdmin
  949.     may use this function.
  950.  
  951. FileOpenForRead: utility
  952. proc utility FileOpenForRead(string fileName)int
  953.  
  954.     FileOpenForRead will open the named file for reading. 'fileName'
  955.     is a full path or is relative to where MUDServ was started. The
  956.     value returned is 0 to indicate some kind of failure, or some
  957.     other value to indicate success. The resulting identifier can be
  958.     used with 'FileRead', and should eventually be closed with
  959.     'FileClose'. Only SysAdmin, or code written by SysAdmin, can use
  960.     FileOpenForRead.
  961.  
  962. FileOpenForWrite: utility
  963. proc utility FileOpenForWrite(string fileName)int
  964.  
  965.     FileOpenForWrite will open the named file for reading. 'fileName'
  966.     is a full path or is relative to where MUDServ was started. The
  967.     value returned is 0 to indicate some kind of failure, or some
  968.     other value to indicate success. The resulting identifier can be
  969.     used with 'FileWrite', and should eventually be closed with
  970.     'FileClose'. Only SysAdmin, or code written by SysAdmin, can use
  971.     FileOpenForWrite. Note that this routine opens the file in the
  972.     Amiga's exclusive mode, and empties the file.
  973.  
  974. FileOpenForUpdate: utility
  975. proc utility FileOpenForUpdate(string fileName)int
  976.  
  977.     FileOpenForUpdate will open the named file for update. 'fileName'
  978.     is a full path or is relative to where MUDServ was started. The
  979.     value returned is 0 to indicate some kind of failure, or some
  980.     other value to indicate success. The resulting identifier can be
  981.     used with 'FileReadBinary', 'FileWrite', 'FileWriteBinary' and
  982.     'FileSeek', and should eventually be closed with 'FileClose'. Only
  983.     SysAdmin, or code written by SysAdmin, can use FileOpenForUpdate.
  984.  
  985. FileRead: utility
  986. proc utility FileRead(int fileId)string
  987.  
  988.     FileRead reads and returns a line from the indicated file. The
  989.     file must have been opened for reading. If the line in the file is
  990.     longer than 512 characters, then only the first 512 are returned,
  991.     but the entire line is consumed in the file. Reading an empty line
  992.     returns a string containing a single space. An end-of-file
  993.     condition on the file returns an empty string. FileRead can only
  994.     be used on a file that was opened using 'FileOpenForRead'.
  995.  
  996. FileReadBinary: utility
  997. proc utility FileReadBinary(int fileId; list int data)int
  998.  
  999.     FileReadBinary reads binary data from the indicated file. The
  1000.     amount of data read is determined by the size of the passed list.
  1001.     For each element in the list, 4 bytes will be read and placed in
  1002.     that element of the list. If there is not enough data in the file,
  1003.     then some elements of the list may not be updated, and one may be
  1004.     only partially updated. The number of bytes read will be returned.
  1005.     This will be no more than 4 times the number of elements in the
  1006.     list. FileWriteBinary can only be used with a file that was opened
  1007.     using 'FileOpenForUpdate'.
  1008.  
  1009. FileSeek: utility
  1010. proc utility FileSeek(int fileId, position)void:
  1011.  
  1012.     The current position in the indicated file will be moved to the
  1013.     given position. Subsequent 'FileReadBinary', 'FileWriteBinary' or
  1014.     'FileWrite' calls will start at that position. FileSeek can only
  1015.     be used on files opened with 'FileOpenForUpdate'.
  1016.  
  1017. FileWrite: utility
  1018. proc utility FileWrite(int fileId; string theString)void
  1019.  
  1020.     FileWrite writes string 'theString' to the open file identified by
  1021.     'fileId'. No modifications are made to the string - it is written
  1022.     exactly as it is given. A runtime error results if 'fileId' is not
  1023.     currently valid, or was not opened for writing. Only SysAdmin, or
  1024.     code owned by SysAdmin, can use FileWrite.
  1025.  
  1026. FileWriteBinary: utility
  1027. proc utility FileWriteBinary(int fileId; list int data)void
  1028.  
  1029.     The data in the list is written as binary data to the file. The
  1030.     data in the list is not modified. The file must have been opened
  1031.     with 'FileOpenForUpdate'. Four bytes of data are written for each
  1032.     element of the list.
  1033.  
  1034. FindActionSymbol: symbols
  1035. proc utility FindActionSymbol(table theTable; action theAction)string
  1036.  
  1037.     FindActionSymbol is used to try to find a symbol, in table
  1038.     'theTable' for action 'theAction'. If such a symbol is found, it
  1039.     is returned, else an empty string is returned. This function is
  1040.     used in the builder code to try to print a symbolic name for an
  1041.     action in a checker list.
  1042.  
  1043. FindAgent: machine/character
  1044. proc utility FindAgent(string name)thing
  1045.  
  1046.     FindAgent is the basic means of identifying a reference to an
  1047.     agent (a player character or a machine) by a user command. It
  1048.     searches the lists of active players and active machines, looking
  1049.     for one in the same room as the active client, whose name matches
  1050.     that given. If 'name' is the name of a player character, then that
  1051.     character is looked for and returned if found in the room.
  1052.     Otherwise, 'name' is matched, using 'MatchName', against all of
  1053.     the machines in the room. The first one matched, if any, is
  1054.     returned. As a special case, the strings "me", "myself", "self"
  1055.     and "yourself" return either the active character or the active
  1056.     machine. This search is done by substituting the "MeString" value
  1057.     for 'name'. Thus, if 'SetMeString' has been used to alter that
  1058.     name, then the altered version is searched for. This technique is
  1059.     used with Packrat, so that commands such as "Give xxx to me" will
  1060.     do the expected thing. If no such agent is found, nil is returned.
  1061.  
  1062. FindAgentAsChild: machine/character
  1063. proc utility FindAgentAsChild(thing room, parent)thing
  1064.  
  1065.     FindAgentAsChild searches for a machine in the indicated room
  1066.     which is a direct child of the thing 'parent'. For example, in the
  1067.     standard scenario, the monsters in the Proving Grounds are
  1068.     normally direct children of the generic monsters defined in
  1069.     "monsters.m". Thus, FindAgentAsChild can be used to search a room
  1070.     for a monster cloned from one of those original models. If no such
  1071.     machine is found, nil is returned.
  1072.  
  1073. FindAgentAsDescendant: machine/character
  1074. proc utility FindAgentAsDescendant(thing room, parent)thing
  1075.  
  1076.     FindAgentAsDescendant is very similar to FindAgentAsChild. The
  1077.     difference is that FindAgentAsDescendant will look all the way
  1078.     back through the parentage chain of each machine it checks, to see
  1079.     if 'parent' is on that chain. Thus if machine "three" inherits
  1080.     from machine "two" which inherits from machine "one" and machine
  1081.     "three" is in the room being searched, then FindAgentAsDescendant
  1082.     will find it, but FindAgentAsChild will not. Both will find
  1083.     machine "two".
  1084.  
  1085. FindAgentAt: machine/character
  1086. proc utility FindAgentAt(thing location; string name)thing
  1087.  
  1088.     FindAgentAt is related to FindAgent. It looks in the given room
  1089.     for a player character or machine whose name matches 'name'.
  1090.     FindAgentAt does NOT do the special handling of "me", etc.
  1091.     however. It is most useful for code which wants to determine if
  1092.     someone or something is in some other specific room. If no such
  1093.     agent is found, nil is returned.
  1094.  
  1095. FindAgentWithChildOnList: machine/character
  1096. proc utility FindAgentWithChildOnList(thing room;
  1097.     property list thing listProp; thing parent)thing
  1098.  
  1099.     FindAgentWithChildOnList performs a search of the form 'look for
  1100.     an agent which has an XXX'. 'room' is the room to search in.
  1101.     'listProp' is the property on the agents which points to a list of
  1102.     things, on which to search for a thing which is a child of
  1103.     'parent'. For example, if a magic fountain is only active if
  1104.     someone or something in the room is carrying the magic doodad,
  1105.     then "FindAgentWithChildOnList(room, p_oCarrying, o_doodad)" will
  1106.     perform the required search. Note that the search will not find
  1107.     the doodad inside a container being carried, nor will it find it
  1108.     in any list other than the one indicated. This, and other similar
  1109.     searches, can be done using AmigaMUD code, but the builtin is much
  1110.     more efficient, provided it performs the required search.
  1111.  
  1112. FindAgentWithFlag: machine/character
  1113. proc utility FindAgentWithFlag(thing room; property bool flagProp)thing
  1114.  
  1115.     FindAgentWithFlag looks for an agent (player character or machine)
  1116.     in the given room which has property 'flagProp' set to true. For
  1117.     example, if a scenario were to define a flag "p_pHasCold",
  1118.     indicating that the player has a cold, then the search for
  1119.     infection could be done by "FindAgentWithFlag(room, p_pHasCold).
  1120.     If no such agent is found, nil is returned.
  1121.  
  1122. FindAgentWithFlagOnList: machine/character
  1123. proc utility FindAgentWithFlagOnList(thing room;
  1124.     property list thing listProp; property bool flagProp)thing
  1125.  
  1126.     FindAgentWithFlagOnList performs a search of the form 'look for an
  1127.     agent which has something which is XXX". 'room' is the room to
  1128.     search in. 'listProp' is the property on the agents which points
  1129.     to a list of things, on which to search for a thing which has
  1130.     property 'flagProp' set to 'true'. The standard scenario uses this
  1131.     routine to see if anyone in a given room is carrying a light with
  1132.     "FindAgentWithFlagOnList(room, p_pCarrying, p_oLight)". Note that
  1133.     the search will not find a light source that is inside a container
  1134.     being carried. If no such agent is found, then nil is returned.
  1135.  
  1136. FindAgentWithNameOnList: machine/character
  1137. proc utility FindAgentWithNameOnList(thing room;
  1138.     property list thing listProp;
  1139.     property string nameProp; string name)thing
  1140.  
  1141.     FindAgentWithNameOnList performs a search of the form 'look for an
  1142.     agent which has something called XXX". 'room' is the room to
  1143.     search in. 'listProp' is the property on the agents which points
  1144.     to a list of things, on which to search for a thing which has
  1145.     string property 'nameProp' which matches 'name'. The searching of
  1146.     the lists is done using 'FindName'. This function is a bit more
  1147.     general than 'FindAgentWithFlagOnList', but it is also quite a bit
  1148.     more expensive to use. Instead of looking for someone with one of
  1149.     a specific type of "apple", this function can look for someone
  1150.     with any kind of "apple", for example.
  1151.  
  1152. FindAnyWord: parsing
  1153. proc utility FindAnyWord(grammar theGrammar; string theWord)int
  1154.  
  1155.     FindAnyWord is a generalization of 'FindWord'. It looks for word
  1156.     'theWord' in the indicated grammar. The id code for the word is
  1157.     returned if it is found, else 0 is returned. If the word is a
  1158.     synonym of another word, then the code of that other word is
  1159.     returned.
  1160.  
  1161. FindChildOnList: database
  1162. proc utility FindChildOnList(list thing theList; thing parent)bool
  1163.  
  1164.     FindChildOnList looks through the elements of 'theList', looking
  1165.     for a thing which is a direct child of 'parent'. If one is found,
  1166.     then FindChildOnList returns 'true', and 'FindResult' can be used
  1167.     to retrieve the actual thing, else 'false' is returned.
  1168.  
  1169. FindElement: database
  1170. proc utility FindElement(<any list> theList;
  1171.     <corresponding element type> valu)int
  1172.  
  1173.     FindElement is a generic routine used to search lists. It works on
  1174.     any kind of list, searching for the corresponding type of value.
  1175.     If the value is found in the list, then the index of the first one
  1176.     is returned, else -1 is returned.
  1177.  
  1178. FindFlagOnList: database
  1179. proc utility FindFlagOnList(list thing theList; property bool flagProp)
  1180.     bool
  1181.  
  1182.     FindFlagOnList is used to search a list of things for a thing
  1183.     which has property 'flagProp' set to true. Note that this search
  1184.     searches for the flag on the things in the list as well as on all
  1185.     of their ancestors. Thus, its result is 'true' if and only if the
  1186.     found thing yields 'true' when looking up the property on it. If
  1187.     such a thing is found, then it can be retrieved with 'FindResult'.
  1188.  
  1189. FindKey: utility
  1190. proc utility FindKey(int key)void
  1191.  
  1192.     FindKey is a very powerful and very expensive routine. It will
  1193.     search the entire database for a symbol whose value is the passed
  1194.     key. The key is normally given as a hexadecimal int constant. All
  1195.     definitions of the key are printed out, one per line, showing the
  1196.     paths of tables to the key. Because of the expense of this
  1197.     function, only SysAdmin can execute it. E.g. if wizard "Fred" has
  1198.     the key in his table "lower" in his table "castle" as "rose", and
  1199.     wizard "Joe" has the key in his table "rooms" as symbol "redRose",
  1200.     then the output would be:
  1201.  
  1202.     FindKey(0xXXXXXXXX).
  1203.     Fred/castle/lower/rose
  1204.     Joe/rooms/redRose
  1205.  
  1206. FindMachineIndexed: machine/character
  1207. proc utility FindMachineIndexed(string name; int index)thing
  1208.  
  1209.     FindMachineIndexed returns the 'index'th machine whose name
  1210.     matches (using MatchName) 'name'. If no such machine exists, then
  1211.     nil is returned. Thus, we can scan through all of the goblins in
  1212.     the scenario with:
  1213.  
  1214.     i := 0;
  1215.     while
  1216.         goblin := FindMachineIndexed("goblin", i);
  1217.         goblin ~= nil
  1218.     do
  1219.         processGoblin(goblin);
  1220.         i := i + 1;
  1221.     od;
  1222.  
  1223.     Note that if "processGoblin" deletes the goblin, this simple loop
  1224.     will skip the next one, so "processGoblin" should return a value
  1225.     indicating that it has done so, and "i" should not be incremented.
  1226.     If it is known beforehand that scanning through all of the goblins
  1227.     is needed, then it is probably easier to just link them together
  1228.     in a big linked list as they are created/destroyed.
  1229.  
  1230. FindName: parsing
  1231. proc utility FindName(list thing theList; property string nameProp;
  1232.     string theName)status
  1233.  
  1234.     FindName is the general string-searching routine in AmigaMUD. It
  1235.     searches the elements of 'theList', looking for a value of string
  1236.     property 'nameProp' which matches 'theName'. Matching is
  1237.     determined by builtin function 'MatchName'. If no such element is
  1238.     found, then 'fail' is returned. If one such element is found, then
  1239.     'succeed' is found, and if more than one is found, 'continue' is
  1240.     returned. If either 'succeed' or 'continue' is returned, then
  1241.     builtin 'FindResult' can be used to return the found thing. Note
  1242.     that the string 'theName' is in the internal "noun;adj,adj" form.
  1243.     If the string begins with a decimal number and a colon, which is
  1244.     the form that 'GetNounPhrase' and 'Parse' yield for the syntax
  1245.     "adj adj noun #number", then the 'continue' result is not
  1246.     possible, and the 'number'th matching thing is returned. In this
  1247.     case, the numbers are one-origin, not the normal zero-origin. E.g.
  1248.  
  1249.     st := FindName(Me()@p_pCarrying, p_oName, name);
  1250.     if st = fail then
  1251.         Print("You aren't carrying any " + FormatName(name));
  1252.     elif st = continue then
  1253.         Print(FormatName(name) + " is ambiguous here");
  1254.     else
  1255.         theThing := FindResult();
  1256.         /* process theThing */
  1257.     fi;
  1258.  
  1259. FindResult: parsing
  1260. proc utility FindResult()thing
  1261.  
  1262.     FindResult is used to return the matching thing from three kinds
  1263.     kinds of searches. These are: 'FindName', 'FindFlagOnList', and
  1264.     'FindChildOnList'.
  1265.  
  1266. FindThingSymbol: symbols
  1267. proc utility FindThingSymbol(table theTable; thing theThing)string
  1268.  
  1269.     FindThingSymbol is used to try to find a symbol, in table
  1270.     'theTable' for thing 'theThing'. If such a symbol is found, it
  1271.     is returned, else an empty string is returned. This function is
  1272.     used in the builder code to supply a symbol for the "current"
  1273.     object.
  1274.  
  1275. FindWord: parsing
  1276. proc utility FindWord(grammar theGrammar; string theWord)int
  1277.  
  1278.     FindWord looks up word 'theWord' in grammar 'theGrammar'. If the
  1279.     word is found, then its unique identifier in the grammar is
  1280.     returned. If the word is not found, then 0 is returned. If the
  1281.     word is not a base definition, i.e. it is a synonym of some other
  1282.     word, then 0 is also returned. See 'FindAnyWord'.
  1283.  
  1284. Flush: database
  1285. proc utility Flush()void
  1286.  
  1287.     Flush forces the internal server caches to be written through to
  1288.     the database files. Its effect is very transitory, however, in
  1289.     that further execution in the server, including by machines, can
  1290.     modify the internal cached forms, thus making the stored forms
  1291.     invalid again. Flush performs the same action as the "MUDFlush"
  1292.     program.
  1293.  
  1294.     It is possible to arrange a time-driven event in AmigaMUD which
  1295.     will call Flush, then use "Execute" to copy the database files to
  1296.     a backup location. This saved copy should be fully complete and
  1297.     valid, as far as the AmigaMUD server is concerned. However, the
  1298.     machines will not have called their "idle actions", nor will any
  1299.     active players. Thus, the saved copy may not be consistent from
  1300.     the point of view of the scenario. An example in the standard
  1301.     scenario would be a Flush when a player is in Questor's office.
  1302.     The stored database has that player present, and therefore will
  1303.     lock others out of that room. If that saved copy of the database
  1304.     is used, then when the server starts up the player will not be
  1305.     active, even though the scenario code thinks he/she/it is in
  1306.     Questor's office. Hence, Questor's office will be unusable until
  1307.     that character is logged in and leaves it. Worse problems will
  1308.     occur with the TimeKeeper machine, since it will not be able to
  1309.     compensate for the time passed while the scenario was not running.
  1310.  
  1311. ForceAction: machine/character
  1312. proc utility ForceAction(thing theAgent; action theAction)status
  1313.  
  1314.     ForceAction is used to force another agent, either a player
  1315.     character or a machine, to perform an action. The action to be
  1316.     performed is the function 'theAction' which must have no
  1317.     parameters and must return a "status" result. That result is
  1318.     returned by ForceAction. When the action is forced, it is executed
  1319.     on behalf of the agent, so that, for example, "Me()" will be that
  1320.     agent, and "Here()" will be that agent's location. "TrueMe()" can
  1321.     still be used to find the agent which is active at the time of the
  1322.     call to ForceAction. The standard scenario uses ForceAction for a
  1323.     number of purposes, including activities relating to killing
  1324.     monsters in combat.
  1325.  
  1326. ForEachAgent: machine/character
  1327. proc utility ForEachAgent(thing location; action theAction)void
  1328.  
  1329.     ForEachAgent is a general routine which can be used to perform
  1330.     searches that the specific 'FindAgentXXX' routines cannot. It can
  1331.     also be used to perform actions on a number of agents. It scans
  1332.     through the active agents, both player characters and machines,
  1333.     and for each one which is in the given location (or for each one
  1334.     if 'location' is nil) calls the passed action with that agent as
  1335.     its parameter. E.g. we can write a routine which will have each
  1336.     agent announce its location:
  1337.  
  1338.     private proc announce(thing theAgent)void:
  1339.         thing where;
  1340.         string m;
  1341.  
  1342.         m := FormatName(theAgent@p_pName) + " is ";
  1343.         where := AgentLocation(theAgent);
  1344.         if where = nil then
  1345.         m := m + "nowhere";
  1346.         else
  1347.         m := m + where@p_rName;
  1348.         fi;
  1349.         APrint(m + ".\n");
  1350.     corp;
  1351.     ForEachAgent(nil, announce).
  1352.  
  1353. ForEachClient: machine/character
  1354. proc utility ForEachClient(action theAction)void
  1355.  
  1356.     ForEachClient is like ForEachAgent, except that it simply scans
  1357.     through all of the active clients in the system. This, in
  1358.     combination with 'ScanTable' used with 'Characters', allows just
  1359.     about any kind of scan needed. Here is some sample code which does
  1360.     the same as the builtin 'APrint':
  1361.  
  1362.     private p_pAnnouncement CreateStringProp().
  1363.  
  1364.     private proc announce(thing who)void:
  1365.         SPrint(who, Me()@p_pAnnouncement);
  1366.     corp;
  1367.  
  1368.     private proc myAPrint(string message)void:
  1369.         Me()@p_pAnnouncement := message;
  1370.         ForEachClient(announce);
  1371.         Me() -- p_pAnnouncement;
  1372.     corp;
  1373.  
  1374. FormatName: output
  1375. proc utility FormatName(string theName)string
  1376.  
  1377.     FormatName converts a string in "internal" noun-phrase form to one
  1378.     in "external" form. The internal form is the form that consists of
  1379.     a noun (or a set of alternatives, separated by commas), optionally
  1380.     followed by a semicolon and a comma-separated list of adjectives.
  1381.     Any number of those complete forms can be given as alternatives,
  1382.     separated by periods. The external form uses only the first
  1383.     complete alternative. It consists of the adjectives, separated by
  1384.     spaces, followed by another space and the first noun alternative.
  1385.     E.g.
  1386.  
  1387.     FormatName("dog") => "dog"
  1388.     FormatName("dog;big,black") => "big black dog"
  1389.     FormatName("dog,pooch;big,black") => "big black dog"
  1390.     FormatName("Spot.dog,pooch;big,black") => "Spot"
  1391.  
  1392. GAMove: effects
  1393. proc utility GAMove(thing who; int x, y)void
  1394.  
  1395.     GAMove moves the drawing cursor (not any displayed curser) of the
  1396.     given client to the given absolute position. Valid absolute
  1397.     positions with the V1.0 MUD client are: 0 <= x < 320, 0 <= y < 99.
  1398.  
  1399. GCircle: effects
  1400. proc utility GCircle(thing who; int r; bool fill)void
  1401.  
  1402.     GCircle draws a circle on the graphics window of the given client.
  1403.     The circle is of radius 'r', and is centered at the current
  1404.     drawing cursor position. The circle is drawn using the currently
  1405.     selected graphics pen. If 'fill' is true, then the circle is
  1406.     filled in, else just an outline is drawn. Note that the entire
  1407.     circle must be within the graphics drawing area, or it will not be
  1408.     drawn.
  1409.  
  1410. GClear: effects
  1411. proc utility GClear(thing who)void
  1412.  
  1413.     GClear clears the entire graphics area of the selected client to
  1414.     the background colour (pen 0).
  1415.  
  1416. GColours: effects
  1417. proc utility GColours(thing who)int
  1418.  
  1419.     GColours returns the number of colours that the indicated client
  1420.     can display. For the V1.0 Amiga "MUD" client, this is 32.
  1421.  
  1422. GCols: effects
  1423. proc utility GCols(thing who)int
  1424.  
  1425.     GCols returns the number of graphics columns that the indicated
  1426.     client can display. For the V1.0 Amiga "MUD" client, this is 320.
  1427.  
  1428. GDefineTile: effects
  1429. proc utility GDefineTile(thing who; int id, width, height;
  1430.     list int data)void
  1431.  
  1432.     GDefineTile sends a tile definition to the indicated client. From
  1433.     then on, that tile can be referenced by 'GDisplayTile' without
  1434.     being sent from the server again. 'id' is a unique identifier for
  1435.     that tile pattern. 'width' and 'height' are the width and height
  1436.     of the tile in pixels. 'data' is an int array whose size must be
  1437.     equal to (width * height + 3) / 4, i.e. the number of pixels
  1438.     rounded up to the nearest 4. Each int in the list represents 4
  1439.     pixels, with 8 bits used for each one. The pixels are stored row
  1440.     by row. For example, here is a routine to return a 32 pixel wide
  1441.     by 20 pixel high tile which is a miniature of the town view in the
  1442.     standard scenario:
  1443.  
  1444.     define t_tiles proc makeTownTile()list int:
  1445.         list int tile;
  1446.     
  1447.         tile := CreateIntArray(160);
  1448.         tile[0] := 0x1d1d1d1d;
  1449.         tile[1] := 0x1d1d1d1d;
  1450.         tile[2] := 0x1d1d1d1d;
  1451.         tile[3] := 0x1d1d0301;
  1452.         tile[4] := 0x0101031d;
  1453.         tile[5] := 0x1d1d1d1d;
  1454.         tile[6] := 0x1d1d1d1d;
  1455.         tile[7] := 0x1d1d1d1d;
  1456.         tile[8] := 0x1d1d1d1d;
  1457.         tile[9] := 0x1d1d1d1d;
  1458.         tile[10] := 0x1d1d1d1d;
  1459.         tile[11] := 0x1d1d0301;
  1460.         tile[12] := 0x0101031d;
  1461.         tile[13] := 0x1d1d1d1d;
  1462.         tile[14] := 0x1d1d1d1d;
  1463.         tile[15] := 0x1d1d1d1d;
  1464.         tile[16] := 0x1d1d1d1d;
  1465.         tile[17] := 0x1d1d1d1d;
  1466.         tile[18] := 0x1d1d1d1d;
  1467.         tile[19] := 0x1d1d0301;
  1468.         tile[20] := 0x0101031d;
  1469.         tile[21] := 0x1d1d1d1d;
  1470.         tile[22] := 0x1d1d1d1d;
  1471.         tile[23] := 0x1d1d1d1d;
  1472.         tile[24] := 0x1d1d1d1d;
  1473.         tile[25] := 0x1d1d1d1d;
  1474.         tile[26] := 0x1d1d1d1d;
  1475.         tile[27] := 0x1d1d0301;
  1476.         tile[28] := 0x0101031d;
  1477.         tile[29] := 0x1d1d1d1d;
  1478.         tile[30] := 0x1d1d1d1d;
  1479.         tile[31] := 0x1d1d1d1d;
  1480.         tile[32] := 0x1d1d1d1d;
  1481.         tile[33] := 0x1d1d1d1d;
  1482.         tile[34] := 0x1d1d1d1d;
  1483.         tile[35] := 0x1d1d0301;
  1484.         tile[36] := 0x0101031d;
  1485.         tile[37] := 0x1d1d1d1d;
  1486.         tile[38] := 0x1d1d1d1d;
  1487.         tile[39] := 0x1d1d1d1d;
  1488.         tile[40] := 0x1d1d1d1d;
  1489.         tile[41] := 0x1d1d1d1d;
  1490.         tile[42] := 0x1d1d1d1d;
  1491.         tile[43] := 0x1d1d0301;
  1492.         tile[44] := 0x0101031d;
  1493.         tile[45] := 0x1d1d1d1d;
  1494.         tile[46] := 0x1d1d1d1d;
  1495.         tile[47] := 0x1d1d1d1d;
  1496.         tile[48] := 0x1d1d1d1d;
  1497.         tile[49] := 0x1d1d1d1d;
  1498.         tile[50] := 0x1d1d1d1d;
  1499.         tile[51] := 0x1d1d0301;
  1500.         tile[52] := 0x0101031d;
  1501.         tile[53] := 0x1d1d1d1d;
  1502.         tile[54] := 0x1d1d1d1d;
  1503.         tile[55] := 0x1d1d1d1d;
  1504.         tile[56] := 0x1d1d1d1d;
  1505.         tile[57] := 0x1d1d1d1d;
  1506.         tile[58] := 0x1d1d1d1d;
  1507.         tile[59] := 0x1d1d0301;
  1508.         tile[60] := 0x0101031d;
  1509.         tile[61] := 0x1d1d1d1d;
  1510.         tile[62] := 0x1d1d1d1d;
  1511.         tile[63] := 0x1d1d1d1d;
  1512.         tile[64] := 0x03030303;
  1513.         tile[65] := 0x03030303;
  1514.         tile[66] := 0x03030303;
  1515.         tile[67] := 0x03030301;
  1516.         tile[68] := 0x01010303;
  1517.         tile[69] := 0x03030303;
  1518.         tile[70] := 0x03030303;
  1519.         tile[71] := 0x03030303;
  1520.         tile[72] := 0x01010101;
  1521.         tile[73] := 0x01010101;
  1522.         tile[74] := 0x01010101;
  1523.         tile[75] := 0x01010101;
  1524.         tile[76] := 0x01010101;
  1525.         tile[77] := 0x01010101;
  1526.         tile[78] := 0x01010101;
  1527.         tile[79] := 0x01010101;
  1528.         tile[80] := 0x01010101;
  1529.         tile[81] := 0x01010101;
  1530.         tile[82] := 0x01010101;
  1531.         tile[83] := 0x01010101;
  1532.         tile[84] := 0x01010101;
  1533.         tile[85] := 0x01010101;
  1534.         tile[86] := 0x01010101;
  1535.         tile[87] := 0x01010101;
  1536.         tile[88] := 0x03030303;
  1537.         tile[89] := 0x03030303;
  1538.         tile[90] := 0x03030303;
  1539.         tile[91] := 0x03030301;
  1540.         tile[92] := 0x01010303;
  1541.         tile[93] := 0x03030303;
  1542.         tile[94] := 0x03030303;
  1543.         tile[95] := 0x03030303;
  1544.         tile[96] := 0x1d1d1d1d;
  1545.         tile[97] := 0x1d1d1d1d;
  1546.         tile[98] := 0x1d1d1d1d;
  1547.         tile[99] := 0x1d1d0301;
  1548.         tile[100] := 0x0101030d;
  1549.         tile[101] := 0x0f0d0d0e;
  1550.         tile[102] := 0x0d030d0d;
  1551.         tile[103] := 0x0f0d0d03;
  1552.         tile[104] := 0x1d1d1d1d;
  1553.         tile[105] := 0x1d1d1d1d;
  1554.         tile[106] := 0x1d1d1d1d;
  1555.         tile[107] := 0x1d1d0301;
  1556.         tile[108] := 0x0101030f;
  1557.         tile[109] := 0x0f0f0e0e;
  1558.         tile[110] := 0x0e030d0f;
  1559.         tile[111] := 0x0f0f0d03;
  1560.         tile[112] := 0x1d1d1d1d;
  1561.         tile[113] := 0x1d1d1d1d;
  1562.         tile[114] := 0x1d1d1d1d;
  1563.         tile[115] := 0x1d1d0301;
  1564.         tile[116] := 0x0101030e;
  1565.         tile[117] := 0x0f0d0d0e;
  1566.         tile[118] := 0x0303030d;
  1567.         tile[119] := 0x0f0d0d03;
  1568.         tile[120] := 0x1d1d1d1d;
  1569.         tile[121] := 0x1d1d1d1d;
  1570.         tile[122] := 0x1d1d1d1d;
  1571.         tile[123] := 0x1d1d0301;
  1572.         tile[124] := 0x01010e0e;
  1573.         tile[125] := 0x0e0d0d1d;
  1574.         tile[126] := 0x0316031d;
  1575.         tile[127] := 0x0d0d0d03;
  1576.         tile[128] := 0x1d1d1d1d;
  1577.         tile[129] := 0x1d1d1d1d;
  1578.         tile[130] := 0x1d1d1d1d;
  1579.         tile[131] := 0x1d1d0301;
  1580.         tile[132] := 0x0101030e;
  1581.         tile[133] := 0x0d0f0d0d;
  1582.         tile[134] := 0x0303030d;
  1583.         tile[135] := 0x0d0f0d03;
  1584.         tile[136] := 0x1d1d1d1d;
  1585.         tile[137] := 0x1d1d1d1d;
  1586.         tile[138] := 0x1d1d1d1d;
  1587.         tile[139] := 0x1d1d0301;
  1588.         tile[140] := 0x0101030d;
  1589.         tile[141] := 0x0f0f0f0d;
  1590.         tile[142] := 0x0d030d0d;
  1591.         tile[143] := 0x0f0f0f03;
  1592.         tile[144] := 0x1d1d1d1d;
  1593.         tile[145] := 0x1d1d1d1d;
  1594.         tile[146] := 0x1d1d1d1d;
  1595.         tile[147] := 0x1d1d0301;
  1596.         tile[148] := 0x0101030d;
  1597.         tile[149] := 0x0d0f0d0d;
  1598.         tile[150] := 0x0d030d0d;
  1599.         tile[151] := 0x0d0f0d03;
  1600.         tile[152] := 0x1d1d1d1d;
  1601.         tile[153] := 0x1d1d1d1d;
  1602.         tile[154] := 0x1d1d1d1d;
  1603.         tile[155] := 0x1d1d0301;
  1604.         tile[156] := 0x01010303;
  1605.         tile[157] := 0x03030303;
  1606.         tile[158] := 0x03030303;
  1607.         tile[159] := 0x03030303;
  1608.         tile
  1609.     corp;
  1610.  
  1611.     The use of hexadecimal for the numbers makes it easier to see the
  1612.     individual pixels, since there are two hexadecimal digits for each
  1613.     one. The value for the pixel is the pen to use to draw that pixel.
  1614.     If the width of the tile is not a multiple of 4, then the values
  1615.     get quite a bit harder to see in this form. This routine was
  1616.     produced by a short program which reads an IFF ILBM image of the
  1617.     tile and writes out the definition of the tile for AmigaMUD. As of
  1618.     the V0.7 release, the scenario does not make use of the tile
  1619.     facility.
  1620.  
  1621. GDeleteIcon: effects
  1622. proc utility GDeleteIcon(thing who, whoseIcon)void
  1623.  
  1624.     GDeleteIcon removes the icon for agent 'whoseIcon' from the
  1625.     display of agent 'who'. The "MUD" program for 'who' also forgets
  1626.     the definition of the icon. This variant is used when the icon is
  1627.     that of a transient machine (like a monster), so that if the same
  1628.     thing key happens to get re-used for another machine, the system
  1629.     will not accidentally display the icon for the old use of that
  1630.     key, rather than the new one. See GRemoveIcon for an example.
  1631.  
  1632. GDisplayTile: effects
  1633. proc utility GDisplayTile(thing who; int id)void
  1634.  
  1635.     GDisplayTile instructs the "MUD" program of 'who' to display the
  1636.     indicated tile at the current drawing position. The top-left
  1637.     corner pixel of the tile will go at the drawing position, and the
  1638.     drawing position will not be changed.
  1639.  
  1640. GEllipse: effects
  1641. proc utility GEllipse(thing who; int a, b; bool fill)void
  1642.  
  1643.     GEllipse is very similar to GCircle, except that it draws an
  1644.     ellipse with major radius 'a' and minor radius 'b'.
  1645.  
  1646. GetIndent: output
  1647. proc utility GetIndent()int
  1648.  
  1649.     GetIndent returns the current output indent value for the active
  1650.     client. See 'SetIndent' for an example.
  1651.  
  1652. GetNounPhrase: parsing
  1653. proc utility GetNounPhrase(grammar theGrammar; string theString;
  1654.     int separator)string
  1655.  
  1656.     GetNounPhase is part of the AmigaMUD input parsing facility. It is
  1657.     normally called internal to 'Parse' as part of parsing a verb with
  1658.     a direct object or both direct and indirect objects. It can be
  1659.     called directly by user code however. It basically strips one noun
  1660.     phrase from the front of the passed string. The noun phrase is
  1661.     terminated by the end of the string, a punctuation mark such as
  1662.     ".", ",", or ";", or by the occurrence of the given separator
  1663.     word, as defined in the given grammar. Note that GetNounPhrase can
  1664.     return an empty string if a terminator is found at the beginning
  1665.     of the passed string. Any leading "a", "an" or "the" will be
  1666.     stripped from the noun phrase. Any leading "#<number" will be
  1667.     placed at the beginning of the returned noun-phrase, separated
  1668.     from the rest of the phrase by a ":". If the scanned input
  1669.     contained only articles ("a", "an", "the") and "#<number>", but no
  1670.     other words, then GetNounPhrase will print "I need a noun in that
  1671.     sentence." and return an empty string. In a successful operation,
  1672.     the part of the input string not consumed by the noun phrase will
  1673.     be left in the "tail buffer" (see 'GetTail', 'SetTail',
  1674.     'GetWord'). The returned string is the parsed noun phrase in
  1675.     AmigaMUD internal form, i.e. <noun;adj,adj,...>.
  1676.  
  1677.     GetNounPhrase is typically used in a 'VerbTail' verb, which is
  1678.     doing nonstandard parsing of an input command. See, for example,
  1679.     its use in Caretaker's input parsing or the "with" verb in the
  1680.     standard scenario. GetNounPhrase can also be used as the inverse
  1681.     of 'FormatName'.
  1682.  
  1683. GetSeed: utility
  1684. proc utility GetSeed()int
  1685.  
  1686.     GetSeed returns the current value of the server's random number
  1687.     seed. This, in combination with 'SetSeed' can be used to generate
  1688.     reproducible pseudo-random events or structures.
  1689.  
  1690. GetString: utility
  1691. proc utility GetString(string initial; action handler; string prompt)void
  1692.  
  1693.     GetString is used to prompt the user for a string value, and to
  1694.     supply it to the scenario code. Note, however, that GetString does
  1695.     not return the string from the user. The server cannot wait for
  1696.     the user to type the string in, so the result comes back
  1697.     indirectly. GetString is passed a handler action, which will be
  1698.     called with the string the user typed in, when the user has
  1699.     finished typing in that string. Because 'GetString' invokes a
  1700.     string requester in the "MUD" client program, it can only be used
  1701.     when the player is using that client program, either locally or
  1702.     remotely. The 'GOn' builtin can be used to test this. 'prompt'
  1703.     will appear as a prompt in the top of the string requester, and
  1704.     'initial' will be the initial contents of the string requester's
  1705.     input area. When the handler action is called, it is called with
  1706.     two parameters. The first is the string, and the second is a bool
  1707.     value indicating whether or not the user aborted out of the string
  1708.     requester. GetString is used in several places in the button
  1709.     operated building code. For example:
  1710.  
  1711.     proc gotNameString(string s; bool ok)void:
  1712.         if ok then
  1713.         if s = "" then
  1714.             Me()@p_pWhichThing -- p_oNameProp;
  1715.         else
  1716.             Me()@p_pWhichThing@p_oNameProp := s;
  1717.         fi;
  1718.         fi;
  1719.         Me() -- p_pWhichThing;
  1720.     corp;
  1721.  
  1722.     proc requestNewName(thing theThing)void:
  1723.         Me()@p_pWhichThing := thing;
  1724.         GetString(theThing@p_oNameProp, gotNameString,
  1725.               "Enter new name:");
  1726.     corp;
  1727.  
  1728. GetTail: parsing
  1729. proc utility GetTail()string
  1730.  
  1731.     GetTail returns the current contents of the server's "tail
  1732.     buffer". This value can be set by 'SetTail', or 'GetNounPhrase',
  1733.     but is usually set by the internal parsing code. When a 'VerbTail'
  1734.     verb is being parsed, the tail buffer is set to contain the
  1735.     remainder of the input command, after the verb. 'GetWord' can be
  1736.     used to pull "words" out of the tail buffer, one at a time. This
  1737.     allows such a verb to do whatever kind of parsing it wants on the
  1738.     input command.
  1739.  
  1740. GetThingStatus: database
  1741. proc utility GetThingStatus(thing theThing)<thing status>
  1742.  
  1743.     GetThingStatus returns the access status of the passed thing. This
  1744.     can be one of: 'ts_public', 'ts_private', 'ts_readonly', and
  1745.     'ts_wizard', as explained in previous documents.
  1746.  
  1747. GettingString: utility
  1748. proc utility GettingString()bool
  1749.  
  1750.     GettingString returns 'true' if there is currently an active
  1751.     client (i.e. the code running is not that for a machine, triggered
  1752.     independently), and that client is already involved in a
  1753.     'GetString' call. Otherwise, it returns 'false'. This can be used
  1754.     to avoid getting run-time errors from trying to use 'GetString'
  1755.     when it is already in use.
  1756.  
  1757. GetWord: parsing
  1758. proc utility GetWord()string
  1759.  
  1760.     GetWord returns the next "word" from the current tail buffer. For
  1761.     this purpose, a "word" is either a string enclosed in quotation
  1762.     marks (") or a word ended with a space. GetWord does not strip off
  1763.     leading spaces before looking for a word. It assumes that that
  1764.     has already been done, which is the case when 'SetTail', or
  1765.     'GetNounPhrase' sets up the tail buffer, and when a VerbTail is
  1766.     being handled. GetWord removes any trailing spaces after the word
  1767.     it returns, thus preserving the assumption. GetWord can return an
  1768.     empty string if the tail buffer is empty, or if it encountered a
  1769.     pair of adjacent quotation marks. GetWord is most often used
  1770.     inside VerbTail verbs, which require special parsing.
  1771.  
  1772. GiveThing: database
  1773. proc utility GiveThing(thing theThing; character theCharacter)void
  1774.  
  1775.     GiveThing changes the ownership of the passed thing to be the
  1776.     passed character. The operation will fail with a runtime error if
  1777.     either is nil, or the current owner of the thing is not the
  1778.     effective player, and the effective player is not SysAdmin.
  1779.     Changing the owner of a thing can be used when giving an object to
  1780.     a different player. It effects the access rights to the thing.
  1781.  
  1782. GLoadBackGround: effects
  1783. proc utility GLoadBackGround(thing who; string name)void
  1784.  
  1785.     GLoadBackGround is a graphic effect routine which instructs the
  1786.     remote "MUD" client to load in a background image. This image is
  1787.     loaded from "AmigaMUD:BackGrounds/<name>" on the client machine.
  1788.     The image should be be at least 320 x 100 pixels. If the IFF file
  1789.     contains a colour palette, then that palette is loaded, and
  1790.     replaces the current one for the entire graphics window. If the
  1791.     background file is not found, nothing is done, but the "failure"
  1792.     flag is set in the client, and can be tested via 'IfFound'.
  1793.  
  1794. GNewIcon: effects
  1795. proc utility GNewIcon(thing theCharacter; list int newIcon)void
  1796.  
  1797.     GNewIcon associates a new icon with the specified character. Icons
  1798.     are attached to the thing as property 'p_pIcon', which is of type
  1799.     "property list int". The list of ints given must be exactly 8
  1800.     elements long. This function is used to assign the new icon value
  1801.     instead of just using a direct assignment statement, since it
  1802.     checks for a valid icon, and it will update the display of any
  1803.     clients who are currently displaying the icon for this character,
  1804.     and will invalidate any copies of the icon in the icon caches of
  1805.     other clients. Icons are 16 pixel by 16 pixel bitmaps which are
  1806.     displayed on top of client graphics images to indicate the
  1807.     presence of the character in the same room as the client's
  1808.     character. Note that icons are not full-colour - they are shown
  1809.     using the currently selected icon colour only. The client "MUD"
  1810.     programs keep a backup copy of the graphics imagery behind the
  1811.     icon, so removing an icon can be done without having to redraw the
  1812.     graphics imagery. Also, the clients keep a cache of all icons that
  1813.     they have seen, so that the icon data does not have to be resent
  1814.     to redisplay the icon.
  1815.  
  1816. GOn: effects
  1817. proc utility GOn(thing who)bool
  1818.  
  1819.     GOn returns 'true' if the indicated client can display graphics.
  1820.     This is currently true only if the client is running the "MUD"
  1821.     client, either locally or remotely. Note that the "MUD" program
  1822.     can hide the graphics window (e.g. while editing), but it will
  1823.     indicate that graphics are "on" at that time, and will update the
  1824.     hidden graphics window appropriately. The "MUD" program can turn
  1825.     graphics off altogether, in which case 'GOn' on that client will
  1826.     return 'false', and graphics effects operations for that client
  1827.     are not sent.
  1828.  
  1829.     GOn is really just an efficiency measure, allowing the scenario to
  1830.     avoid executing a bunch of graphics-related code if the results
  1831.     would be discarded anyway.
  1832.  
  1833. GPalette: effects
  1834. proc utility GPalette(thing who)bool
  1835.  
  1836.     GPalette on a given client returns 'true' if that client has a
  1837.     palette containing alterable graphics pens. A client running on a
  1838.     system which has only fixed colours would return 'false'. The
  1839.     scenario does not currently use this information.
  1840.  
  1841. GPixel: effects
  1842. proc utility GPixel(thing who)void
  1843.  
  1844.     GPixel writes a single pixel, using the current graphics pen, at
  1845.     the current graphics position, on the indicated client. Neither
  1846.     the pen nor the position are changed.
  1847.  
  1848. GPolygonEnd: effects
  1849. proc utility GPolygonEnd(thing who)void
  1850.  
  1851.     GPolygonEnd is used to close off and draw the current polygon. See
  1852.     GPolygonStart for an example.
  1853.  
  1854. GPolygonStart: effects
  1855. proc utility GPolygonStart(thing who)void
  1856.  
  1857.     GPolygonStart starts drawing a polygon on the indicated client.
  1858.     The polygon will be filled with the current graphics pen. The
  1859.     sides of the polygon are defined using the 'GRDraw' effects
  1860.     routine. Multiple polygons can be drawn at once by using the
  1861.     'GAMove' and 'GRMove' routines to move without drawing. For
  1862.     example, the following code uses polygon drawing to draw part of
  1863.     the "doors room" in the Proving Grounds, as seen from beyond the
  1864.     doors:
  1865.  
  1866.     define tp_proving5 PR_DOORS2_ID NextEffectId().
  1867.     define tp_proving5 proc drawDoors2()void:
  1868.     
  1869.         if not KnowsEffect(nil, PR_DOORS2_ID) then
  1870.         DefineEffect(nil, PR_DOORS2_ID);
  1871.         GSetImage(nil, "pr_doors2");
  1872.         IfFound(nil);
  1873.             GShowImage(nil, "", 0, 0, 160, 100, 0, 0);
  1874.         Else(nil);
  1875.             GSetPen(nil, C_DARK_GREY);
  1876.             GAMove(nil, 0, 0);
  1877.             GRectangle(nil, 159, 99, true);
  1878.     
  1879.             GSetPen(nil, C_LIGHT_GREY);
  1880.             GPolygonStart(nil);
  1881.             GAMove(nil, 70, 99);
  1882.             GRDraw(nil, -10, -19);
  1883.             GRDraw(nil, -20, 0);
  1884.             GRDraw(nil, 0, -20);
  1885.             GRDraw(nil, 20, -20);
  1886.             GRDraw(nil, 40, 0);
  1887.             GRDraw(nil, 20, 20);
  1888.             GRDraw(nil, 0, 20);
  1889.             GRDraw(nil, -20, 0);
  1890.             GRDraw(nil, -10, 19);
  1891.             GPolygonEnd(nil);
  1892.     
  1893.             drawDoors1();
  1894.         Fi(nil);
  1895.         EndEffect();
  1896.         fi;
  1897.         CallEffect(nil, PR_DOORS2_ID);
  1898.     corp;
  1899.  
  1900. GRDraw: effects
  1901. proc utility GRDraw(thing who; int deltaX, deltaY)void
  1902.  
  1903.     GRDraw is used to draw a line, starting at the current graphics
  1904.     position, moving the relative X-Y distance specified by the passed
  1905.     delta values. The graphics drawing position is updated to the new
  1906.     position. The line is drawn using the current graphics pen.
  1907.  
  1908. GRectangle: effects
  1909. proc utility GRectangle(thing who; int width, height; bool fill)void
  1910.  
  1911.     GRectangle is used to draw a rectangle on the graphics window of
  1912.     the indicated client. The top-left corner of the rectangle is at
  1913.     the current graphics position. The bottom-right corner is
  1914.     determined by the passed 'width' and 'height' values. If 'fill' is
  1915.     'true', then the rectangle is filled with the current graphics pen,
  1916.     else only the border of the rectangle is drawn with that pen. Note
  1917.     that the rectangle is actually drawn as one larger than the
  1918.     indicated 'width' and 'height', since both the top-left and the
  1919.     bottom-right corners are considered to be within the rectangle.
  1920.     This can be a little misleading, but it was felt to be simpler
  1921.     then describing the subtraction of 1 from the values to get the
  1922.     coordinates of the lower-right corner. Thus, to fill the entire
  1923.     graphics window on the "MUD" client, one could use:
  1924.  
  1925.     GSetPen(nil, <colour>);
  1926.     GAMove(nil, 0, 0);
  1927.     GRectangle(nil, 159, 99);
  1928.  
  1929. GRedrawIcons: effects
  1930. proc utility GRedrawIcons(thing who)void
  1931.  
  1932.     GRedrawIcons causes the selected client "MUD" program to redisplay
  1933.     all of the icons that it believes should currently be displayed.
  1934.     This, in combination with 'GUndrawIcons', allows the graphics
  1935.     imagery behind the icons to be changed without having to manually
  1936.     remove and then re-draw all of the icons. Note that 'PlaceCursor'
  1937.     and 'RemoveCursor' should also be used, to make sure that the
  1938.     cursor appears again. If the entire graphics display is going to
  1939.     be redrawn, then 'GUndrawIcons' and 'RemoveCursor' need not be
  1940.     used. For example, to make a small change to the graphics display,
  1941.     e.g. opening or closing a door, etc., the following could be used:
  1942.  
  1943.     ...
  1944.     RemoveCursor();
  1945.     GUndrawIcons(nil);
  1946.     /* modify picture */
  1947.     GRedrawIcons(nil);
  1948.     PlaceCursor(cursorX, cursorY);
  1949.     ...
  1950.  
  1951.     Note that 'RemoveCursor' and 'PlaceCursor' operate implicitly on
  1952.     the active client, so most situations of changing the display for
  1953.     a given room should use 'ForEachAgent' to cause the displays of
  1954.     all clients whose characters are in the room to be properly
  1955.     updated.
  1956.  
  1957. GRemoveIcon: effects
  1958. proc utility GRemoveIcon(thing who, whoseIcon)void
  1959.  
  1960.     GRemoveIcon removes the display of the icon for character
  1961.     'whoseIcon' from the display of client 'who'. The pattern of the
  1962.     icon is not removed from 'who's icon cache. This is the normal way
  1963.     to remove an icon from a display - 'GDeleteIcon' is used when the
  1964.     client should also forget the definition of the icon. This needs
  1965.     to be done, for example, when 'whoseIcon' represents a monster
  1966.     being killed, in which case the thing for the monster might be
  1967.     soon re-used for another monster that should have a different
  1968.     icon. Here is how this is handled in the standard scenario:
  1969.  
  1970.     /*
  1971.      * UnShowIcon - remove my icon from anyone else here.
  1972.      */
  1973.     
  1974.     define t_icons proc utility UnShowIconOnce(thing th)void:
  1975.         thing me;
  1976.     
  1977.         me := Me();
  1978.         if (me@p_pIcon ~= nil or me@p_pStandard) and Parent(me) = nil
  1979.         then
  1980.         /* If the player or machine has a specific icon, or
  1981.            this is a player or a "standard" machine (Packrat,
  1982.            etc.), and this is not a cloned entity, then we
  1983.            just tell the client to undisplay the icon, but to
  1984.            remember it for later use. */
  1985.         GRemoveIcon(th, me);
  1986.         else
  1987.         /* Otherwise, we tell the client to undisplay the icon, 
  1988.            but also to forget it, since the thing associated
  1989.            with it may be reused later for something with a
  1990.            different icon. */
  1991.         GDeleteIcon(th, me);
  1992.         fi;
  1993.     corp;
  1994.     
  1995.     define t_icons proc utility public UnShowIcon()void:
  1996.     
  1997.         ForEachAgent(Here(), UnShowIconOnce);
  1998.     corp;
  1999.  
  2000. GResetColours: effects
  2001. proc utility GResetColours(thing who)void
  2002.  
  2003.     GResetColours resets the graphics palette of the indicated client
  2004.     to the default set of colours:
  2005.  
  2006.     0x000,        /* 00 - black */
  2007.     0x777,        /* 01 - dark grey */
  2008.     0x999,        /* 02 - medium grey */
  2009.     0xccc,        /* 03 - light grey */
  2010.     0xfff,        /* 04 - white */
  2011.     0xd00,        /* 05 - brick red */
  2012.     0xf00,        /* 06 - red */
  2013.     0xf80,        /* 07 - red-orange */
  2014.     0xf90,        /* 08 - orange */
  2015.     0xfc0,        /* 09 - gold */
  2016.     0xfd0,        /* 10 - cadmium yellow */
  2017.     0xff0,        /* 11 - lemon yellow */
  2018.     0xbf0,        /* 12 - lime green */
  2019.     0x0f0,        /* 13 - green */
  2020.     0x8e0,        /* 14 - light green */
  2021.     0x2c0,        /* 15 - dark green */
  2022.     0x0b1,        /* 16 - forest green */
  2023.     0x0ca,        /* 17 - blue green */
  2024.     0x0db,        /* 18 - aqua */
  2025.     0x1fb,        /* 19 - light aqua */
  2026.     0x6fe,        /* 20 - sky blue */
  2027.     0x6ce,        /* 21 - light blue */
  2028.     0x00f,        /* 22 - blue */
  2029.     0x69f,        /* 23 - dark blue */
  2030.     0xc1f,        /* 24 - violet */
  2031.     0xc0e,        /* 25 - purple */
  2032.     0xf1f,        /* 26 - magenta */
  2033.     0xfac,        /* 27 - pink */
  2034.     0xdb9,        /* 28 - tan */
  2035.     0xc80,        /* 29 - brown */
  2036.     0xa70,        /* 30 - medium brown */
  2037.     0xa87        /* 31 - dark brown */
  2038.  
  2039. GResetIcons: effects
  2040. proc utility GResetIcons(thing who)void
  2041.  
  2042.     GResetIcons instructs the indicated client to believe that it
  2043.     currently has no icons displayed. This is quicker when moving from
  2044.     room to room (i.e. icon-set to icon-set) than removing all of the
  2045.     individual icons. Note that this routine does not remove the icon
  2046.     imagery from the graphics window. Any icons which were initially
  2047.     displayed as "temporary" (see 'GShowIcon'), are removed from the
  2048.     client's icon cache.
  2049.  
  2050. GRMove: effects
  2051. proc utility GRMove(thing who; int deltaX, deltaY)void
  2052.  
  2053.     GRMove moves the graphics cursor in the indicated direction from
  2054.     its current position. No drawing on the screen takes place. This
  2055.     routine can also be used while drawing a polygon, and has a
  2056.     similar effect.
  2057.  
  2058. GRows: effects
  2059. proc utility GRows(thing who)int
  2060.  
  2061.     GRows returns the number of rows of pixels in the graphics window
  2062.     of the indicated client. Currently, the only graphics client is
  2063.     the "MUD" client, and it has 100 rows of pixels. If the client in
  2064.     use does not support graphics, then 0 is returned.
  2065.  
  2066. GScrollRectangle: effects
  2067. proc utility GScrollRectangle(thing who;
  2068.     int xDelta, yDelta, x1, y1, x2, y2)void
  2069.  
  2070.     GScrollRectangle instructs the client to shift a rectangular
  2071.     region of its graphics window. The coordinates of the top-left and
  2072.     bottom-right corners of the affected rectangle are given. The
  2073.     delta values indicate the direction in which to scroll the
  2074.     rectangle. Positive values for the deltas indicate scrolling away
  2075.     from the top-left corner in that direction. Data scrolled out of a
  2076.     side of the rectangle is lost. The contents of the region of the
  2077.     rectangle scrolled away from is undefined. One good use of
  2078.     GScrollRectangle is in implementing a scrolling map-view type of
  2079.     display: when the character walks off of the edge of the visible
  2080.     area (or comes close), use GScrollRectangle to scroll the entire
  2081.     graphics window, and then fill in the scrolled-from area with
  2082.     tiles or imagery for newly visible terrain.
  2083.  
  2084. GSetColour: effects
  2085. proc utility GSetColour(thing who; int which, colour)void
  2086.  
  2087.     GSetColour sets graphics pen 'which' in client 'who' to colour
  2088.     'colour'. For the Amiga "MUD" client, the 'which' values can range
  2089.     from 0 to 31, and the 'colour' value is a 12 bit RGB value (4 bits
  2090.     of red, 4 bits of green, and 4 bits of blue).
  2091.  
  2092. GSetIconPen: effects
  2093. proc utility GSetIconPen(thing who; int colour)void
  2094.  
  2095.     GSetIconPen sets which pen (colour) is to be used to draw icons in
  2096.     the graphics window. The entire set of icons currently displayed
  2097.     by the client is redrawn using the new pen.
  2098.  
  2099. GSetImage: effects
  2100. proc utility GSetImage(thing who; string name)void
  2101.  
  2102.     GSetImage sets the given image name to be the current "active"
  2103.     image. The active image is used by 'GShowImage' if 'GShowImage' is
  2104.     passed an empty string. With the Amiga "MUD" client program, path
  2105.     "AmigaMUD:Images/" is prepended to the image name. If the image
  2106.     file is found, it is loaded into the client's cache. If it is not
  2107.     found, nothing happens, but the "failed" flag is set in the
  2108.     client, and can be tested by subsequent 'IfFound' tests.
  2109.  
  2110. GSetPen: effects
  2111. proc utility GSetPen(thing who; int pen)void
  2112.  
  2113.     GSetPen sets the pen to use for subsequent graphics operations,
  2114.     such as line drawing, rectangles, circles, polygons, etc.
  2115.  
  2116. GSetTextColour: effects
  2117. proc utility GSetTextColour(thing who; int which, colour)void
  2118.  
  2119.     GSetTextColour sets the colour of pen 'which' in client 'who',
  2120.     used in the text window. In the Amiga "MUD" client, pen numbers
  2121.     can be from 0 to 3, and 'colour' is a 12 bit RGB value, with 4
  2122.     bits for red, 4 bits for green, and 4 bits for blue. Note that
  2123.     setting the text colours will also affect either the background of
  2124.     the text window, or one of the border-and-menu colours, so the
  2125.     colours used should be selected carefully.
  2126.  
  2127. GShowBrush: effects
  2128. proc utility GShowBrush(thing who; string name;
  2129.     int displayX, displayY)void
  2130.  
  2131.     GShowBrush overlays a brush image onto the graphics window at the
  2132.     indicated position. The brush is loaded from "AmigaMUD:Brushes/
  2133.     <name>". If the brush file cannot be found, then nothing happens,
  2134.     but the "not found" flag is set, and can be tested by 'IfFound'.
  2135.     The difference between a brush and an image is that a brush has
  2136.     either a mask plane or a background colour, so that it can be
  2137.     overlayed on top of the existing graphics as a non-rectangular
  2138.     shape.
  2139.  
  2140. GShowIcon: effects
  2141. proc utility GShowIcon(thing who, whoseIcon;
  2142.     bool isMonster, isTemporary)void
  2143.  
  2144.     GShowIcon shows the icon for character (or NPC) 'whoseIcon' on the
  2145.     graphics window of client 'who'. If the client has no record of
  2146.     the indicated icon, then it will either use the default non-
  2147.     monster icon (the smiley face) or the default monster icon (the
  2148.     growly thing), depending on 'isMonster'. If the icon is displayed
  2149.     as temporary, then when a 'GResetIcons' is done, the icon is
  2150.     deleted from the client completely. This is used when 'whoseIcon'
  2151.     is inheriting its icon from a parent thing, since then 'whoseIcon'
  2152.     is not a unique identifier for the icon.
  2153.  
  2154. GShowImage: effects
  2155. proc utility GShowImage(thing who; string name;
  2156.     int imageX, imageY, imageWidth, imageHeight, displayX, displayY)void
  2157.  
  2158.     GShowImage loads an IFF image file from "AmigaMUD:Images/<name>"
  2159.     onto the graphics window. The image is placed with its top-left
  2160.     corner at 'displayX', 'displayY', and is taken from the whole
  2161.     image file at offset 'imageX', 'imageY', with size 'imageWidth' by
  2162.     'imageHeight'. Being able to display a smaller segment from a
  2163.     large image file allows one image file to contain several images.
  2164.     For example, one file could contain all of the needed images to
  2165.     represent a 3D maze view. This allows the entire set of images to
  2166.     be accessed quickly, and treated as a whole in the client's cache.
  2167.     Also, making changes to the set of images can be easier if they
  2168.     are all displayed at once in a paint program.
  2169.  
  2170. GText: effects
  2171. proc utility GText(thing who; string text)void
  2172.  
  2173.     GText displays the given string as text, using the default system
  2174.     font, in the current graphics pen, at the current graphics
  2175.     position, in the given client's graphics window. The graphics
  2176.     position is moved up to just past the end of the text (such that
  2177.     another GText would append the text properly). Note that, in the
  2178.     Amiga "MUD" client, the current position row is used as the
  2179.     position for the baseline of the font, which is the conceptual
  2180.     line drawn at the bottom of the non-descending part of the
  2181.     characters.
  2182.  
  2183. GType: effects
  2184. proc utility GType(thing who)string
  2185.  
  2186.     GType returns the name of the graphics display of the client.
  2187.     Since the Amiga "MUD" client is the only client so far, the value
  2188.     returned is "Amiga".
  2189.  
  2190. GUndrawIcons: effects
  2191. proc utility GUndrawIcons(thing who)void
  2192.  
  2193.     GUndrawIcons instructs the specified client to remove all of the
  2194.     currently displayed icons from the graphics window. The client
  2195.     does not forget about the icons, it only undraws them (by
  2196.     replacing the background imagery which was saved when the icons
  2197.     were drawn). GUndrawIcons, in combination with 'GRedrawIcons', can
  2198.     be used to allow easy modification of the imagery that is "behind"
  2199.     the icons. See GRedrawIcons.
  2200.  
  2201. HasAdjective: parsing
  2202. proc utility HasAdjective(string name, adjective)bool
  2203.  
  2204.     HasAdjective returns 'true' if the given 'name', which must be in
  2205.     the standard AmigaMUD "noun;adj,adj..." form, contains 'adjective'
  2206.     as one of its adjectives. Note that HasAdjective handles only a
  2207.     simple internal form for the name - multiple alternatives are not
  2208.     handled.
  2209.  
  2210. Here: machine/character
  2211. proc utility Here()thing
  2212.  
  2213.     Here returns the current location of the active character (or
  2214.     machine.) The return value can be nil if the character has no
  2215.     location. The location of something can be set by the calls
  2216.     'SetLocation', 'SetCharacterLocation' and 'SetAgentLocation'.
  2217.  
  2218. IfFound: effects
  2219. proc utility IfFound(thing who)void
  2220.  
  2221.     This effect routine causes the specified client to test the last-
  2222.     set value of its "not found" flag, and either enable or disable
  2223.     the execution of effects code as a result. See GPolygonStart for a
  2224.     typical example of using IfFound.
  2225.  
  2226. Index: utility
  2227. proc utility Index(string s1, s2)int
  2228.  
  2229.     Index returns the index in string 's1' of the first (leftmost)
  2230.     occurrence of string 's2'. Index positions, like string substring
  2231.     positions, start with index 0. If string 's2' cannot be found in
  2232.     string 's1', then Index returns -1.
  2233.  
  2234. IntToString: utility
  2235. proc utility IntToString(int n)string
  2236.  
  2237.     IntToString returns a string containing the decimal form of the
  2238.     passed int value. If the value is negative, the returned string
  2239.     will start with a minus sign, but no plus sign is inserted for
  2240.     positive values of 'n'.
  2241.  
  2242. IPrint: output
  2243. proc utility IPrint(int number)void
  2244.  
  2245.     IPrint prints the decimal form of 'number' to the current client.
  2246.     It is equivalent to "Print(IntToString(number))", but a bit more
  2247.     efficient, since it doesn't have to allocate and free a string,
  2248.     and is only one call instead of two.
  2249.  
  2250. IsAncestor: database
  2251. proc utility IsAncestor(thing myKey, parentKey)bool
  2252.  
  2253.     IsAncestor returns 'true' if 'parentKey' is the parent of 'myKey',
  2254.     or the parent of the parent of 'myKey', or the parent of... i.e.
  2255.     it returns 'true' if 'parentKey' is on the ancestor chain of
  2256.     'myKey'.
  2257.  
  2258. IsApprentice: machine/character
  2259. proc utility IsApprentice()bool
  2260.  
  2261.     IsApprentice returns 'true' if the active client is a player, and
  2262.     that player is an apprentice.
  2263.  
  2264. IsAre: output
  2265. proc utility IsAre(string s1, s2, s3, s4)string
  2266.  
  2267.     IsAre eases the output of correct English for plural nouns. This
  2268.     is perhaps best described by examples:
  2269.  
  2270.     IsAre("There", "no", "pie", "here.")  => "There is no pie here."
  2271.     IsAre("There", "no", "pies", "here.") => "There are no pies here."
  2272.     IsAre("There", "", "pie", "here.")      => "There is a pie here."
  2273.     IsAre("There", "", "apple", "here.")  => "There is an apple here."
  2274.     IsAre("There", "", "pies", "here.")   => "There are some pies here."
  2275.  
  2276.     If 's2' is empty, then IsAre uses either "a" or "an", depending on
  2277.     whether 's3' starts with a consonant or a vowel ("aeiou"). It uses
  2278.     "is" or "are" depending on whether 's3' ends in an "s" or not.
  2279.     Note that this test for plurality can easily be wrong. Note also
  2280.     that IsAre inserts all needed spaces.
  2281.  
  2282. IsDefined: symbols
  2283. proc utility IsDefined(table theTable; string name)bool
  2284.  
  2285.     IsDefined returns 'true' if string 'name' is defined in table
  2286.     'theTable', else it returns 'false'. If 'theTable' is nil, then
  2287.     'name' is looked up in all "in-use" tables.
  2288.  
  2289. IsNormal: machine/character
  2290. proc utility IsNormal()bool
  2291.  
  2292.     IsNormal returns 'true' if the active agent is a player who has
  2293.     status 'normal'.
  2294.  
  2295. IsProgrammer: machine/character
  2296. proc utility IsProgrammer()bool
  2297.  
  2298.     IsProgrammer returns 'true' if the active agent is a player who
  2299.     has status 'wizard' or 'apprentice', i.e. is someone who can do
  2300.     programming.
  2301.  
  2302. IsWizard: machine/character
  2303. proc utility IsWizard()bool
  2304.  
  2305.     IsWizard returns 'true' if the active agent is a player who has
  2306.     status 'wizard'.
  2307.  
  2308. It: utility
  2309. proc utility It()thing
  2310.  
  2311.     It returns the thing last set via 'SetIt'. The thing stored in
  2312.     this special "global variable" is reset to nil whenever a message
  2313.     arrives at the server, and whenever 'Parse' starts a new command.
  2314.     Thus It is valid only during the parsing of one input command. By
  2315.     convention, It is the object (in the English language sense) of
  2316.     the current input sentence, if there is one. See the description
  2317.     of programming within the standard scenario for information on how
  2318.     It is used in that scenario. See also: 'ItName', 'WhoName.
  2319.  
  2320. ItName: parsing
  2321. proc utility ItName()string
  2322.  
  2323.     ItName returns a string containing the internal form of the noun
  2324.     phrase used with a 'Verb1' verb, or the first noun phrase (the
  2325.     direct object) used with a 'Verb2' verb. ItName is maintained
  2326.     directly by the AmigaMUD parser ('Parse'). Similarly, 'WhoName'
  2327.     returns the internal form string of the indirect object (the
  2328.     second noun phrase) associated with a 'Verb2' verb. The only use
  2329.     of ItName in the standard scenario is in a "getaction" attached to
  2330.     a fake bugtape piece in the toolshed - it is used to see if the
  2331.     phrase the player gave for the object contained the words "long"
  2332.     or "longer", via 'HasAdjective'. See also: 'WhoName'.
  2333.  
  2334. KnowsEffect: effects
  2335. proc utility KnowsEffect(thing who; int whichEffect)bool
  2336.  
  2337.     KnowEffect returns 'true' if client 'who' knows the contents of
  2338.     effect 'whichEffect'. This is asking if the client "MUD" program
  2339.     has already been sent the definition of the effect, so that it
  2340.     doesn't have to be sent again (via 'DefineEffect') before being
  2341.     called up (via 'CallEffect').
  2342.  
  2343. Length: utility
  2344. proc utility Length(string str)int
  2345.  
  2346.     Length returns the number of characters in the passed string. This
  2347.     includes any special newline or tab characters. The length of an
  2348.     empty string is 0.
  2349.  
  2350. Log: utility
  2351. proc utility wizard Log(string message)void
  2352.  
  2353.     Log causes the passed string to be appended to the server's "MUD.
  2354.     log" file. This is used in the standard scenario for commands like
  2355.     "complain", "typo", etc. Log can also be used to record error
  2356.     situations. Care should be taken, however, to not Log too much,
  2357.     else the MUD.log file can grow very large. That is why this
  2358.     function is restricted to full wizards.
  2359.  
  2360. LookupAction: symbols
  2361. proc utility LookupAction(table theTable; string name)action
  2362.  
  2363.     'name' is looked up in 'theTable'. If it is found, and the symbol
  2364.     is an action, then that action is returned, else nil is returned.
  2365.     If 'theTable' is nil, then 'name' is looked up in all currently
  2366.     "in-use" tables.
  2367.  
  2368. LookupCounter: symbols
  2369. proc utility LookupCounter(table theTable; string name)property int
  2370.  
  2371.     'name' is looked up in 'theTable'. If it is found, and the symbol
  2372.     is an int property, then that property is returned, else nil is
  2373.     returned. If 'theTable' is nil, then 'name' is looked up in all
  2374.     currently "in-use" tables.
  2375.  
  2376. LookupFlag: symbols
  2377. proc utility LookupFlag(table theTable; string name)property bool
  2378.  
  2379.     'name' is looked up in 'theTable'. If it is found, and the symbol
  2380.     is a bool property, then that property is returned, else nil is
  2381.     returned. If 'theTable' is nil, then 'name' is looked up in all
  2382.     currently "in-use" tables.
  2383.  
  2384. LookupString: symbols
  2385. proc utility LookupString(table theTable; string name)property string
  2386.  
  2387.     'name' is looked up in 'theTable'. If it is found, and the symbol
  2388.     is a string property, then that property is returned, else nil is
  2389.     returned. If 'theTable' is nil, then 'name' is looked up in all
  2390.     currently "in- use" tables.
  2391.  
  2392. LookupTable: symbols
  2393. proc utility LookupTable(table theTable; string name)table
  2394.  
  2395.     'name' is looked up in 'theTable'. If it is found, and the symbol
  2396.     is a table, then that table is returned, else nil is returned. If
  2397.     'theTable' is nil, then 'name' is looked up in all currently "in-
  2398.     use" tables.
  2399.  
  2400. LookupThing: symbols
  2401. proc utility LookupThing(table theTable; string name)thing
  2402.  
  2403.     'name' is looked up in 'theTable'. If it is found, and the symbol
  2404.     is a thing, then that thing is returned, else nil is returned. If
  2405.     'theTable' is nil, then 'name' is looked up in all currently "in-
  2406.     use" tables.
  2407.  
  2408. MakeApprentice: machine/character
  2409. proc utility MakeApprentice(character who; bool doNow)void
  2410.  
  2411.     The given character is made into an apprentice. If 'doNow' is
  2412.     'true', and the character is currently connected, then the client
  2413.     the character is connected through is immediately put into "wizard
  2414.     mode". The status of SysAdmin cannot be changed, and only full
  2415.     wizards can change someone's status. The wizard who promotes a
  2416.     character is recorded as that character's sponsor.
  2417.  
  2418. MakeNormal: machine/character
  2419. proc utility MakeNormal(character who)void
  2420.  
  2421.     The given player is made into a normal player. Only SysAdmin can
  2422.     demote someone, and SysAdmin cannot demote himself. If the player
  2423.     was an apprentice or wizard, and was currently active in wizard
  2424.     mode, then the character's client is immediately forced out of
  2425.     wizard mode.
  2426.  
  2427. MakeWizard: machine/character
  2428. proc utility MakeWizard(character who; bool doNow)void
  2429.  
  2430.     The given character is made into a full wizard. If 'doNow' is
  2431.     'true', and the character is currently connected, then the client
  2432.     the character is connected through is immediately put into "wizard
  2433.     mode". The status of SysAdmin cannot be changed, and only full
  2434.     wizards can change someone's status. The wizard who promotes a
  2435.     character is recorded as that character's sponsor.
  2436.  
  2437. MatchName: parsing
  2438. proc utility MatchName(string stored, parsed)int
  2439.  
  2440.     MatchName is the bottom-level of the AmigaMUD routines which tie
  2441.     together input commands and the database. It matches an internal
  2442.     form of a user input noun phrase against an internal form of a
  2443.     stored one. The stored internal form can have several noun phrase
  2444.     alternatives, separated by periods. Each internal form consists of
  2445.     a comma-separated list of noun alternatives, possibly followed by
  2446.     a semicolon and a comma-separated list of adjectives. There must
  2447.     be no spaces anywhere. If the parsed form can be matched by any of
  2448.     the stored forms, then the index of that stored form (the first is
  2449.     index 0) is returned. If none of the stored forms can match the
  2450.     parsed form, then -1 is returned. Examples:
  2451.  
  2452.     stored                    parsed        result
  2453.     ------------------------------------------------------------------
  2454.     dog,pooch,canine;large,black.Fido        pooch;black    0
  2455.     dog,pooch,canine;large,black.Fido        fido        1
  2456.     dog,pooch,canine;large,black.Fido        Fido;black    -1
  2457.     dog,pooch,canine;large,black.Fido        dog;black,large 0
  2458.     dog,pooch,canine;large,black.Fido        canine        0
  2459.     shelf;wooden.shelf,shelve,shelving;wood,wooden
  2460.                         shelves;wood    1
  2461.                         shelf;wooden    0
  2462.                         shelves;wooden    1
  2463.                         shelving;wood    1
  2464.  
  2465.     Note that excess trailing 's's on the parsed nouns are assumed to
  2466.     be for pluralization and are ignored. Also, case is ignored. The
  2467.     'shelf' example illustrates the use of two alternatives, the first
  2468.     of which is "clean", in that it will come out nicely via
  2469.     'FormatName', and the second of which contains lots of forms, so a
  2470.     variety of user input forms will work.
  2471.  
  2472. Me: utility
  2473. proc utility Me()thing
  2474.  
  2475.     Me returns the thing associated with the active agent. This can be
  2476.     a player character or a machine. Me can never return nil.
  2477.  
  2478. MeCharacter: utility
  2479. proc utility MeCharacter()character
  2480.  
  2481.     MeCharacter returns the character for an active player character.
  2482.     If the active agent is a machine, then MeCharacter returns the
  2483.     character of the owner of the active machine.
  2484.  
  2485. Mine: database
  2486. proc utility Mine(thing theThing)bool
  2487.  
  2488.     Mine returns 'true' if the passed thing is owned by the current
  2489.     effective player.
  2490.  
  2491. MOn: effects
  2492. proc utility MOn(thing who)bool
  2493.  
  2494.     MOn returns 'true' if the indicated client currently has music
  2495.     playing enabled. As of version 0.7, music is not implemented in
  2496.     the "MUD" client, so this function is irrelevant.
  2497.  
  2498. MoveSymbol: symbols
  2499. proc utility MoveSymbol(table fromTable, toTable; string name)bool
  2500.  
  2501.     MoveSymbol moves symbol 'name' from table 'fromTable' to table
  2502.     'toTable'. MoveSymbol will not move symbols to or from the
  2503.     Character or Builtin tables, and will not add a duplicate symbol
  2504.     to 'toTable'. Each table must either be the public table, or owned
  2505.     by the effective player, or the effective player must be SysAdmin.
  2506.  
  2507. MPlaySong: effects
  2508. proc utility MPlaySong(thing who; string name; int id)void
  2509.  
  2510.     MPlaySong starts the playing of a song in the indicated client.
  2511.     The song is loaded from "AmigaMUD:Music/<name>". If the indicated
  2512.     song cannot be found, then nothing is done, and the "not found"
  2513.     flag is set, and can be tested by 'IfFound'. 'id' is an identifier
  2514.     associated with the playing of the song, and will be given as the
  2515.     second parameter to a call to the character's "effectdone action"
  2516.     triggered when the song finishes playing or is aborted with
  2517.     'AbortEffect'. The first parameter will be 2 for a music effect.
  2518.  
  2519. MVolume: effects
  2520. proc utility MVolume(thing who; int volume)void
  2521.  
  2522.     MVolume sets the volume for music that is played in the indicated
  2523.     client. The default volume is full volume, which is represented as
  2524.     10000; thus a value of 5000 is half volume.
  2525.  
  2526. NewCharacterPassword: utility
  2527. proc utility wizard NewCharacterPassword()void
  2528.  
  2529.     NewCharacterPassword triggers a sequence of events between the
  2530.     server and the client whereby the client is asked to enter and
  2531.     verify a new password. If verified, the new password is entered as
  2532.     the character's password.
  2533.  
  2534. NewCreationPassword: utility
  2535. proc utility NewCreationPassword()void
  2536.  
  2537.     NewCreationPassword triggers a sequence of events between the
  2538.     server and the client whereby the client is asked to enter and
  2539.     verify a new password. If verified, the new password is entered as
  2540.     the new character creation password. This builtin can only be
  2541.     called directly by SysAdmin. If the character creation password is
  2542.     empty, then no password is needed to create a new character. If
  2543.     the new password starts with an asterisk ('*'), then new
  2544.     characters cannot be created by clients, but must be manually
  2545.     created by SysAdmin, using 'CreateCharacter'.
  2546.  
  2547. Normal: utility
  2548. proc utility Normal()void
  2549.  
  2550.     Normal puts the active client into normal (non-wizard) mode, if it
  2551.     is not already in that mode. If the active character is a newly
  2552.     created one that has not yet connected, then the new character
  2553.     action is run for that character. Normal will fail at that point
  2554.     if the scenario does not have a handler proc for text input.
  2555.  
  2556. Note: utility
  2557. proc utility Note()void
  2558.  
  2559.     Note prints a copyright notice to the active client.
  2560.  
  2561. NPrint: output
  2562. proc utility NPrint(string str)void
  2563.  
  2564.     NPrint is much the same as 'Print', except that it will not print
  2565.     newlines. It will stop before any newline in the string that it is
  2566.     passed. NPrint prints a single newline at the end of the string.
  2567.     NPrint also temporarily sets the status of the active client to
  2568.     "wizard", so that no '@'s will appear in front of the output line.
  2569.     NPrint is used to print an arbitrarily retrieved string, in a way
  2570.     that doesn't unnecessarily include the leading '@'s, but in a way
  2571.     that precludes most "spoofing" by apprentices and wizards.
  2572.  
  2573. NukeClient: machine/character
  2574. proc utility NukeClient(character who)void
  2575.  
  2576.     NukeClient violently forces the indicated character out of the
  2577.     game. No attempt is made to nicely shut the character down by
  2578.     allowing the character's "inactive action" to run. This routine
  2579.     should be used only as a last resort, since it can leave things in
  2580.     a confused state.
  2581.  
  2582. OPrint: output
  2583. proc utility OPrint(string str)void
  2584.  
  2585.     OPrint prints the passed string to all clients in the same room
  2586.     (with the same location) as the active client, except the active
  2587.     client. If used from a machine, then the string is printed to all
  2588.     clients in the same room as the machine.
  2589.  
  2590. Owner: database
  2591. proc utility Owner(thing theThing)character
  2592.  
  2593.     Owner returns the character who owns the passed thing. Note that
  2594.     it is a character value that is returned, not that character's
  2595.     thing.
  2596.  
  2597. Parent: database
  2598. proc utility Parent(thing theThing)thing
  2599.  
  2600.     Parent returns the parent thing of the passed thing. The returned
  2601.     value can be nil if the thing has no parent. A thing's parent is
  2602.     the first in the chain of other things that it will inherit
  2603.     properties from.
  2604.  
  2605. Parse: parsing
  2606. proc utility Parse(grammar theGrammar; string sentence)int
  2607.  
  2608.     Parse is the starting point for the internal parsing capabilities
  2609.     of AmigaMUD. It is passed a grammar to parse with, and a string
  2610.     containing one or more commands to be parsed. The commands in the
  2611.     string are separated by periods or semicolons. Each command is
  2612.     assumed to start with a verb, and that verb is looked up in the
  2613.     grammar. If the verb is not found, then Parse will complain "I
  2614.     don't know the word XXX.\n" and will return without parsing any
  2615.     more sentences. Similar errors in handling the expected noun
  2616.     phrases for the verb also result in early termination. Parse
  2617.     returns the number of commands that were successfully parsed and
  2618.     executed. Note that early termination can also be triggered by the
  2619.     semantic code associated with the verbs. See the section on
  2620.     parsing in file "ProgConcepts.txt" for much more information.
  2621.  
  2622. PlaceCursor: effects
  2623. proc utility PlaceCursor(int x, y)void
  2624.  
  2625.     PlaceCursor instructs the "MUD" client program for the active
  2626.     client to place the cursor at position 'x', 'y'. If the cursor was
  2627.     already shown somewhere, then it is removed from that location,
  2628.     and the background imagery and icons replaced, before it is
  2629.     redrawn at the new location.
  2630.  
  2631. Pluralize: output
  2632. proc utility Pluralize(string str)string
  2633.  
  2634.     Pluralize uses simple checks to attempt to pluralize the passed
  2635.     string, and return the new result. The rules that Pluralize uses
  2636.     are:
  2637.  
  2638.     if the string ends in "y" then
  2639.         if there is a vowel before the "y", add s"
  2640.         else replace the "y" with "ies"
  2641.     if the string ends in "x", "s", "i" or "o", add "es"
  2642.     otherwise, add "s"
  2643.  
  2644.     Note: the rules here have changed since the original releases.
  2645.  
  2646.     Examples:
  2647.     toy => toys, day => days, guy => guys
  2648.     fly => flies, try => tries
  2649.     box => boxes, kiss => kisses, potato => potatoes
  2650.     dog => dogs, bill => bills
  2651.  
  2652. Pose: machine/character
  2653. proc utility Pose(string alternateName, what)void
  2654.  
  2655.     If 'alternateName' is an empty string, the name of the active
  2656.     agent is used. That name, formatted, followed by a space and then
  2657.     string "what", is printed to all clients in the same room as the
  2658.     active agent. Also, the same string is passed to a generated call
  2659.     to the "poseAction" of all machines in the same room which have
  2660.     one. The order in which these things happen is not defined.
  2661.  
  2662. Print: output
  2663. proc utility Print(string str)void
  2664.  
  2665.     Print is the basic output function in AmigaMUD. The passed string
  2666.     is printed to the active client, if there is one. As with all
  2667.     other output to a client, the system will word-wrap and indent the
  2668.     output text into the output width of the client's display.
  2669.  
  2670. PrintAction: output
  2671. proc utility PrintAction(action theAction)void
  2672.  
  2673.     A textual, pretty-printed representation of the passed action is
  2674.     printed to the active client. The only current use for this
  2675.     builtin is in the standard scenario's building code, when the user
  2676.     asks to describe the direction checkers on an exit.
  2677.  
  2678. PrintNoAts: output
  2679. proc utility PrintNoAts(bool flag)bool
  2680.  
  2681.     This builtin allows the selection of whether or not '@'s are
  2682.     prepended to all output lines which contain text produced by
  2683.     AmigaMUD code written by apprentices rather than full wizards.
  2684.     This provision is made so that players who wish to be protected
  2685.     from possible "spoofing" by apprentices can be, while those who
  2686.     like such things as part of the game can allow it to be unmarked.
  2687.     In the standard scenario, this is used by the "ats" verb.
  2688.  
  2689. PrivateTable: utility
  2690. proc utility PrivateTable()table
  2691.  
  2692.     PrivateTable returns the private symbol table of the active
  2693.     client. Machines do not have symbol tables. The private symbol
  2694.     table, like the public symbol table and the Builtin table, is
  2695.     always "in-use".
  2696.  
  2697. PublicTable: utility
  2698. proc utility PublicTable()table
  2699.  
  2700.     PublicTable returns the public symbol table. The public symbol
  2701.     table, like the client's private symbol table and the Builtin
  2702.     table, is always "in-use".
  2703.  
  2704. QueryFile: effects
  2705. proc utility QueryFile(string path; action handler)void
  2706.  
  2707.     QueryFile can be used (with some difficulty) by a scenario to find
  2708.     out if the remote client has a given file under the AmigaMUD:
  2709.     directory tree. The 'path' should not contain the "AmigaMUD:"
  2710.     prefix - this is added on by the system. A request is sent off to
  2711.     the client to check for the file. The client checks, then sends a
  2712.     reply back. When the reply arrives, the server will call the
  2713.     supplied 'handler' action, passing a single bool parameter, which
  2714.     is 'true' if the file was found, and 'false' otherwise. This test
  2715.     can be used to make a quick check for an image or tiles file, so
  2716.     that the server can avoid sending over a large effect or set of
  2717.     tiles, which are not actually needed. Remember that the server can
  2718.     never wait for a client, thus this indirect way of getting an
  2719.     answer from the client must be used. The file querying capability
  2720.     exists only in the full 'MUD' client. GOn can be used to see if
  2721.     the user is running the full client.
  2722.  
  2723. Quit: utility
  2724. proc utility Quit()void
  2725.  
  2726.     Quit sets a flag on the active client, so that when the processing
  2727.     of the current message is complete, that client will be shut down
  2728.     and terminated. This is the standard way for a client to exit from
  2729.     the MUD via a command. Exiting in this way, like an exit request
  2730.     directly from a client (e.g. the close box in "MUD"), allows the
  2731.     client's "idle action" to be executed. In the standard scenario
  2732.     this action is used to do any area specific exit actions, such as
  2733.     moving the character out of SysAdmin's office; to make the current
  2734.     room dark if the character had the only source of light; to print
  2735.     a message indicating the character is exiting; and to clear some
  2736.     properties on the client thing.
  2737.  
  2738. Random: utility
  2739. proc utility Random(int range)int
  2740.  
  2741.     Random returns a random integer between zero and one less than the
  2742.     passed range. E.g. Random(2) will return 0 or 1. The random number
  2743.     seed used by Random can be accessed via 'GetSeed' and 'SetSeed'.
  2744.     The random number generator used is seeded by the time of day at
  2745.     the server, and is a version of the minimal standard generator as
  2746.     described in "Random Number Generators: Good Ones are Hard to
  2747.     Find" by Stephen K. Park and Keith W. Miller in Volume 31 Number
  2748.     10 of the Communications of the ACM.
  2749.  
  2750. RemHead: database
  2751. proc utility RemHead(<any list> theList)void
  2752.  
  2753.     RemHead removes the head (first) element from the passed list. The
  2754.     list will now have one less element then it had before, and all
  2755.     elements will be shuffled one position towards the front.
  2756.  
  2757. RemoveCursor: effects
  2758. proc utility RemoveCursor()void
  2759.  
  2760.     RemoveCursor removes the cursor from the active client's graphics
  2761.     window. The background and icons behind the cursor are put back as
  2762.     of when the cursor was drawn.
  2763.  
  2764. RemTail: database
  2765. proc utility RemTail(<any list> theList)void
  2766.  
  2767.     RemTail removes the tail (last) element from the passed list. The
  2768.     list will now have one less element then it had before, but all
  2769.     other elements are still at the same place as they were.
  2770.  
  2771. RenameSymbol: symbols
  2772. proc utility RenameSymbol(table theTable; string oldName, newName)bool
  2773.  
  2774.     RenameSymbol changes the name of symbol 'oldName' in table
  2775.     'theTable' to be 'newName'. The effective user must own the table
  2776.     or be SysAdmin, or the table must be the public table. 'oldName'
  2777.     must exist in the table, and 'newName' must not.
  2778.  
  2779. RunLimit: utility
  2780. proc utility RunLimit(int newValue)int
  2781.  
  2782.     RunLimit sets the execution time limit within the MUD to be the
  2783.     given number of seconds. The old limit is returned. MUDServ
  2784.     enforces this limit for the processing of each message from a
  2785.     client (and hence of the processing of each input line, keypad
  2786.     keypress, mouse action, effect completion, etc.) and for the
  2787.     processing resulting from a machine or client's 'After' code. If
  2788.     the limit is exceeded, the execution is aborted and MUDServ goes
  2789.     on to the next input message or 'After' event. Time spent in the
  2790.     database code flushing the cache does not count as execution time.
  2791.     This limit should be fairly large (I use 100 seconds) while
  2792.     compiling a large scenario, but should be smaller (I use 10
  2793.     seconds) during normal operation. An even smaller limit may be
  2794.     appropriate on faster processors.
  2795.  
  2796. Say: machine/character
  2797. proc utility Say(string alternateName, what)void
  2798.  
  2799.     If 'alternateName' is an empty string, then the name of the active
  2800.     agent is used. That name, formatted, followed by " says: ", and
  2801.     string "what" is printed to all clients in the same room as the
  2802.     active agent. Also, the same string is passed to a generated call
  2803.     to the "sayAction" of all machines in the same room which have
  2804.     one. The order in which these things happen is not defined. The
  2805.     standard scenario has a wrapper, 'DoSay', around Say, which checks
  2806.     for and calls a "sayChecker" in the current room, and which will
  2807.     optionally echo the say back to the active client.
  2808.  
  2809. ScanTable: symbols
  2810. proc utility wizard ScanTable(table theTable; action theAction)void
  2811.  
  2812.     The symbols in the table are scanned (in no defined order), and
  2813.     the name of each is passed as the parameter to a call to action
  2814.     'theAction'. This allows code to do something for each symbol in a
  2815.     table. In particular, the "Characters" table can be scanned to get
  2816.     the names of all characters in the MUD, active or inactive.
  2817.  
  2818. SelectName: parsing
  2819. proc utility SelectName(string names; int which)string
  2820.  
  2821.     SelectName returns a substring of 'names' which is the 'which'th
  2822.     internal-form name within it. Indexing starts at 0, and if the
  2823.     index is out of range, an empty string is returned. E.g.
  2824.  
  2825.     "dog;big.puppy;red.canine;large,ferocious" 0 => "dog;big"
  2826.     "dog;big.puppy;red.canine;large,ferocious" 1 => "puppy;red"
  2827.     "dog;big.puppy;red.canine;large,ferocious" 2 =>
  2828.         "canine;large,ferocious"
  2829.     "dog;big.puppy;red.canine;large,ferocious" 4 => ""
  2830.  
  2831.     Actually, SelectName simply returns the 'which'th period-separated
  2832.     substring of a string. SelectName is useful for extracting the
  2833.     name indicated by a successful 'MatchName' call.
  2834.  
  2835. SelectWord: parsing
  2836. proc utility SelectWord(string words; int which)string
  2837.  
  2838.     SelectWord returns the 'which'th comma- or period- separated
  2839.     substring of the passed 'words' string. E.g.
  2840.  
  2841.     "red,blue,green.yellow,cyan"    0 => "red"
  2842.     "red,blue,green.yellow,cyan"    1 => "blue"
  2843.     "red,blue,green.yellow,cyan"    2 => "green"
  2844.     "red,blue,green.yellow,cyan"    3 => "yellow"
  2845.     "red,blue,green.yellow,cyan"    4 => "cyan"
  2846.     "red,blue,green.yellow,cyan"    5 => ""
  2847.  
  2848. ServerVersion: utility
  2849. proc utility ServerVersion()int
  2850.  
  2851.     ServerVersion returns the version of the MUDAgent server, as an
  2852.     integer. The integer is the actual version number times 10. E.g.
  2853.     for V0.7 of the server, ServerVersion returns 7, and for V1.0 it
  2854.     will return 10.
  2855.  
  2856. SetAgentLocation: machine/character
  2857. proc utility wizard SetAgentLocation(thing agent, where)void
  2858.  
  2859.     SetAgentLocation sets the location of the passed agent to be the
  2860.     passed thing. This can be used to "teleport" a player or machine
  2861.     to some other location. Note that other things would have to be
  2862.     done in a typical scenario. SetAgentLocation will only work on an
  2863.     active character - inactive characters are not agents.
  2864.  
  2865. SetButtonPen: effects
  2866. proc utility SetButtonPen(int which, pen)void
  2867.  
  2868.     SetButtonPen selects pen 'pen' of the graphics pens to be the
  2869.     'which'th button pen. The button pens are as follows:
  2870.  
  2871.     pen    default         use
  2872.     -------------------------------------------------
  2873.      0    1 - dark grey        background of letters
  2874.      1    9 - gold        letters
  2875.      2    2 - medium grey     outer border colour
  2876.      3    3 - light grey        middle border colour
  2877.      4    4 - white        inner border colour
  2878.      5    9 - gold        background of highlighted letters
  2879.      6    1 - dark grey        highlighted letters
  2880.  
  2881. SetCharacterActiveAction: machine/character
  2882. proc utility wizard SetCharacterActiveAction(action newAction)action
  2883.  
  2884.     SetCharacterActiveAction sets the action that is executed whenever
  2885.     the character becomes active, i.e. connects to the MUD after not
  2886.     being connected. It is NOT called when the character is first
  2887.     being initialized - the "new character action" set by
  2888.     'SetNewCharacterAction' is executed then, and that is when the
  2889.     "active action" is usually set up. The old "active action", if
  2890.     any, is returned. The "active action" is usually used to do
  2891.     something like a "look around" command to display graphics, etc.
  2892.     for the user, and to create a standard set of mouse-buttons. The
  2893.     action used must have no parameters and no result.
  2894.  
  2895. SetCharacterButtonAction: machine/character
  2896. proc utility wizard SetCharacterButtonAction(action newAction)action
  2897.  
  2898.     SetCharacterButtonAction sets the action that will be called by
  2899.     the system in response to a button-click in the Amiga "MUD" client
  2900.     program. The action must have one int parameter (the identifier
  2901.     of the button clicked) and no result. The old "button action", if
  2902.     any, is returned.
  2903.  
  2904. SetCharacterEffectDoneAction: machine/character
  2905. proc utility wizard SetCharacterEffectDoneAction(action newAction)action
  2906.  
  2907.     SetCharacterEffectDoneAction sets the action that is called by the
  2908.     system when an effect completes on the client for the active
  2909.     character, or is aborted using 'AbortEffect'. The action must have
  2910.     two int parameters. The first is a code indicating which kind of
  2911.     action is completing:
  2912.  
  2913.     0 => sound
  2914.     1 => speech
  2915.     2 => music
  2916.  
  2917.     The second parameter is the identifier for the particular effect
  2918.     that is completing (or has been aborted with 'AbortEffect'), as
  2919.     given when the effect was started. This routine can be used to
  2920.     create continuously-running or looping graphical, sound and
  2921.     musical effects. The old such action, if any, is returned.
  2922.  
  2923. SetCharacterIdleAction: machine/character
  2924. proc utility wizard SetCharacterIdleAction(action newAction)action
  2925.  
  2926.     SetCharacterIdleAction sets on the active character the action to
  2927.     be called by the system when the character leaves the game. The
  2928.     action must have no parameters and no result. Note that the action
  2929.     is not called if the client is forced out of the game with
  2930.     'NukeClient' (that is how to get rid of a client when its "idle
  2931.     action" goes into an infinite loop when there is a very long
  2932.     timeout in effect!) The "idle action" will often do things like
  2933.     taking the character out of single-occupancy areas like Questor's
  2934.     Office in the standard scenario, and other scenario-dependent
  2935.     character shutdown things. The previous "idle action" for the
  2936.     character, if any, is returned.
  2937.  
  2938. SetCharacterInputAction: machine/character
  2939. proc utility wizard SetCharacterInputAction(action newAction)action
  2940.  
  2941.     SetCharacterInputAction sets on the active character the action to
  2942.     be called by the system when the player running the character
  2943.     enters an input line when not in "wizard mode". The action must
  2944.     have one string parameter - the input line entered, and no result.
  2945.     The action will typically check for one or two special cases (like
  2946.     a leading " or :), and then pass most lines to the AmigaMUD
  2947.     'Parse' function for general parsing. The character's previous
  2948.     "input action", if any, is returned.
  2949.  
  2950. SetCharacterLocation: machine/character
  2951. proc utility SetCharacterLocation(character theCharacter;
  2952.     thing newLocation)void
  2953.  
  2954.     SetCharacterLocation sets the location of character 'theCharacter'
  2955.     to be the given thing. Unlike 'SetAgentLocation', this routine can
  2956.     be used on a character that is not currently active. It cannot,
  2957.     however, be used on a machine. See also: 'SetLocation'.
  2958.  
  2959. SetCharacterMouseDownAction: machine/character
  2960. proc utility wizard SetCharacterMouseDownAction(action newAction)action
  2961.  
  2962.     SetCharacterMouseDownAction sets on the active character the
  2963.     action that the system will call when the user clicks the left
  2964.     mouse button and releases it inside a defined rectangular "mouse
  2965.     region" set up with 'AddRegion'. The action must have 3 int
  2966.     parameters and no result. When called, it is passed the identifier
  2967.     of the region clicked in (supplied to 'AddRegion') and the x and y
  2968.     coordinates of the click relative to the top-left corner of the
  2969.     region. "mouse down" actions are used for things like the icon
  2970.     editor in the standard scenario. The previous "mouse down" action,
  2971.     if any, is returned.
  2972.  
  2973. SetCharacterRawKeyAction: machine/character
  2974. proc utility wizard SetCharacterRawKeyAction(action newAction)action
  2975.  
  2976.     SetCharacterRawKeyAction sets on the active character the action
  2977.     that the system will call when the user presses a numeric keypad
  2978.     key or other special key supported by the system. This allows the
  2979.     scenario to control the shortcut actions performed in response to
  2980.     those keypresses. The keycodes supported in this way are:
  2981.  
  2982.     scenario symbol   value (hex)    meaning
  2983.     -------------------------------------------
  2984.     KEY_HELP        0x0020    HELP key
  2985.     KEY_KP_UL        0x0001    keypad 7
  2986.     KEY_KP_U        0x0002    keypad 8
  2987.     KEY_KP_UR        0x0003    keypad 9
  2988.     KEY_KP_L        0x0004    keypad 4
  2989.     KEY_KP_C        0x0005    keypad 5
  2990.     KEY_KP_R        0x0006    keypad 6
  2991.     KEY_KP_DL        0x0007    keypad 1
  2992.     KEY_KP_D        0x0008    keypad 2
  2993.     KEY_KP_DR        0x0009    keypad 3
  2994.     KEY_KP_PLUS        0x000a    keypad +
  2995.     KEY_KP_MINUS        0x000b    keypad -
  2996.     
  2997.     The previous "rawkey action", if any, is returned.
  2998.  
  2999. SetContinue: utility
  3000. proc utility SetContinue(bool state)void
  3001.  
  3002.     SetContinue instructs the parser whether or not to allow the
  3003.     definition of actions that contain errors. If the state is set to
  3004.     'true', then such actions are defined and entered into the
  3005.     database. They cannot be executed, however. If the state is set to
  3006.     'false', then an error in defining an action (proc) prevents it
  3007.     from being entered into any symbol tables. The normal state will
  3008.     be 'false'. The 'true' state is useful when sourcing large source
  3009.     files so that an error in one function will not cause further
  3010.     errors, in functions which call the first, due to the first not
  3011.     being defined.
  3012.  
  3013. SetCursorPattern: effects
  3014. proc utility SetCursorPattern(list int newPattern)void
  3015.  
  3016.     SetCursorPattern sets the pattern to be used for the graphics
  3017.     cursor available in the graphics window. Like icons, the cursor,
  3018.     manipulated by 'PlaceCursor' and 'RemoveCursor', is a 16 pixel by
  3019.     16 pixel pattern in a single colour ('SetCursorPen'). The list of
  3020.     ints used to define the cursor must have exactly 8 elements (16 *
  3021.     16 / 32), even if the defined cursor is not fully 16 x 16. The
  3022.     cursor pattern is sent to the client, and will take effect
  3023.     immediately if the cursor is currently visible.
  3024.  
  3025. SetCursorPen: effects
  3026. proc utility SetCursorPen(int pen)void
  3027.  
  3028.     SetCursorPen selects the pen to be used for drawing the cursor in
  3029.     the graphics window. The pen is any of the graphics drawing pens.
  3030.     If the cursor is currently visible, it will be redrawn in the new
  3031.     colour. Note that neither SetCursorPen nor SetCursorPattern can
  3032.     directly affect a client other than the one for the active player.
  3033.     If needed, that can be accomplished using 'ForceAction'.
  3034.  
  3035. SetEffectiveTo: utility
  3036. proc utility SetEffectiveTo(character thePlayer)void
  3037.  
  3038.     SetEffectiveTo sets the "effective character", i.e. the one whose
  3039.     access rights are to be in effect, to 'thePlayer'. For obvious
  3040.     security reasons, only SysAdmin, or code written by SysAdmin, can
  3041.     use this function. In other words, the effective player can only
  3042.     be changed in this way if it is currently SysAdmin. The effective
  3043.     player is usually set automatically to the owner of any function
  3044.     called, if that function is not marked as 'utility'. The
  3045.     "effective status" is set to 'apprentice', giving only apprentice
  3046.     access rights.
  3047.  
  3048. SetEffectiveToNone: utility
  3049. proc utility SetEffectiveToNone()void
  3050.  
  3051.     SetEffectiveToNone sets the "effective character" to be no-one.
  3052.     This removes any access that was previously available via the
  3053.     effective player. Any wizard or apprentice can use this function,
  3054.     since it only removes access rights. The "effective status" is set
  3055.     to 'normal', giving neither apprentice nor wizard access rights.
  3056.  
  3057. SetEffectiveToReal: utility
  3058. proc utility SetEffectiveToReal()void
  3059.  
  3060.     SetEffectiveToReal sets the "effective character" back to the real
  3061.     character, i.e. the active character or the owner of the active
  3062.     machine. This is only allowed if the effective character is
  3063.     SysAdmin, since it involves the addition of access rights. The
  3064.     "effective status" is set to the status of the real player, giving
  3065.     whatever access that real player has.
  3066.  
  3067. SetIndent: output
  3068. proc utility wizard SetIndent(int newIndent)void
  3069.  
  3070.     SetIndent sets the current output indentation column. Subsequent
  3071.     lines of output, via 'Print', or any other mechanism, will be
  3072.     indented on the left by 'newIndent'. This is useful when printing
  3073.     lists of things, such as inventories, contents, etc. This, in
  3074.     combination with automatic word wrap and the ability to set the
  3075.     output width, almost makes AmigaMUD seem like a little text
  3076.     formatter. The programmer is advised to check that things are
  3077.     working out correctly, however, since things get complicated with
  3078.     text going to multiple clients, and with some clients desiring '@
  3079.     's in front of any line containing apprentice-generated output.
  3080.     Because of the buffering of output text that is done (each use of
  3081.     'Print', etc. does not cause a separate message to the remote
  3082.     client), the effect of SetIndent will not take place until after a
  3083.     newline has been output. SetIndent should be called before
  3084.     outputting the newline that the indent is desired after. The
  3085.     indent amount is a very short-lived value. It is cleared at the
  3086.     end of each top-level handler call done by the server. See also:
  3087.     'SetPrefix'.
  3088.  
  3089. SetIt: utility
  3090. proc utility SetIt(thing theThing)void
  3091.  
  3092.     SetIt sets the value of the 'It' global variable, which is
  3093.     accessible via the 'It' builtin. See the description of 'It' for
  3094.     more details.
  3095.  
  3096. SetLocation: machine/character
  3097. proc utility wizard SetLocation(thing where)void
  3098.  
  3099.     SetLocation sets the location of the active character or machine
  3100.     to the given thing. This is the most common way of moving from one
  3101.     room to another (in conjunction with other scenario-specific
  3102.     things of course).
  3103.  
  3104. SetMachineActive: machine/character
  3105. proc utility SetMachineActive(thing machine; action theAction)action
  3106.  
  3107.     SetMachineActive sets, on the machine structure associated with
  3108.     'machine', the action that will be called by the system on behalf
  3109.     of that machine (with 'Me' set accordingly) when the server is
  3110.     restarted. This allows the machine to restart its periodic
  3111.     actions, and do any other system-startup initializations. The
  3112.     machine's previous "active action", if any, is returned.
  3113.  
  3114. SetMachineIdle: machine/character
  3115. proc utility SetMachineIdle(thing machine; action theAction)action
  3116.  
  3117.     SetMachineIdle sets, on the machine structure associated with
  3118.     'machine', the action that will be called by the system on behalf
  3119.     of that machine (with 'Me' set accordingly) when the server is
  3120.     being shut down. This allows the machine to do any shutdown
  3121.     activities that the scenario might need. The old "idle action", if
  3122.     any, is returned. The standard scenario uses this capability with
  3123.     the 'TimeKeeper' machine to subtract off the shutdown time from
  3124.     the wait time of each of its events.
  3125.  
  3126. SetMachineOther: machine/character
  3127. proc utility SetMachineOther(thing machine; action theAction)action
  3128.  
  3129.     SetMachineOther sets, on the machine structure associated with
  3130.     'machine', the action that will be called by the system whenever
  3131.     any agent in the same room as the machine calls 'OPrint',
  3132.     'ABPrint', 'Pose' or 'Say'. The text passed to those routines is
  3133.     passed to the action setup by SetMachineOther, and can then be
  3134.     processed by the machine. This allows the programmer to set up
  3135.     machines that watch what is happening in a given room, and which
  3136.     can then pass it on (e.g. a TV camera), record it, or perform
  3137.     actions based on it. Note that this facility, being quite general,
  3138.     is fairly expensive. Thus, programmers should seek less general,
  3139.     but cheaper alternatives wherever possible. Also note that it is
  3140.     unwise to use either of 'OPrint' or 'ABPrint' from inside a
  3141.     handler set up by SetMachineOther, as this can, if care is not
  3142.     taken, result in an infinite recursion loop.
  3143.  
  3144. SetMachinePose: machine/character
  3145. proc utility SetMachinePose(thing machine; action theAction)action
  3146.  
  3147.     SetMachinePose sets, on the machine structure associated with
  3148.     'machine', the action that will be called by the system whenever
  3149.     any agent does a 'Pose' in the room the machine is in. The action
  3150.     must have one string parameter, which will be the string passed to
  3151.     the 'Pose' builtin, with the posing agent's name prefixed. This
  3152.     allows a machine to respond to things like people waving, etc. The
  3153.     previous "pose action", if any, is returned. The standard scenario
  3154.     uses a "pose action" on Packrat to allow her to copy any pose that
  3155.     anyone nearby does.
  3156.  
  3157. SetMachinesActive: machine/character
  3158. proc utility SetMachinesActive(bool state)void
  3159.  
  3160.     SetMachinesActive controls whether or not machines are to be
  3161.     active at all in the scenario. A value of 'false' for 'state'
  3162.     makes machines inactive. This control is useful for debugging, and
  3163.     for controlling wayward machines.
  3164.  
  3165.     If this flag is 'false', then the time until a machine action is
  3166.     to happen is never decreased for any machines. Thus, if an action
  3167.     for a machine is scheduled for 2 seconds, it will never actually
  3168.     happen. However, if the flag is set to 'true', the action will
  3169.     again be scheduled for 2 seconds in the future. This provides a
  3170.     way to keep machines from executing, without stopping them
  3171.     completely, and without changing their timing relationships.
  3172.  
  3173. SetMachineSay: machine/character
  3174. proc utility SetMachineSay(thing machine; action theAction)action
  3175.  
  3176.     SetMachineSay sets, on the machine structure associated with
  3177.     'machine', the action that will be called by the system whenever
  3178.     any agent does a 'Say' in the room the machine is in. The action
  3179.     must have one string parameter, which will be the string passed to
  3180.     the 'Say' builtin, with the speaking agent's name prefixed. This
  3181.     allows machines to respond to spoken commands and comments. The
  3182.     previous "say action", if any, is returned. The standard scenario
  3183.     uses machine "say actions" in a number of places. 'SetSay' can be
  3184.     used to easily pull off the added parts of the string.
  3185.  
  3186. SetMachineWhisperMe: machine/character
  3187. proc utility SetMachineWhisperMe(thing machine; action theAction)action
  3188.  
  3189.     SetMachineWhisperMe sets, on the machine structure associated with
  3190.     'machine', the action that will be called by the system whenever
  3191.     any agent whispers directly to the machine. The action must have
  3192.     one string parameter, which will be the text whispered, preceeded
  3193.     by "<name> whispers:", where <name> is the formatted name of the
  3194.     agent doing the whispering. The previous "whisperme action", if
  3195.     any, is returned. 'SetWhisperMe' can be used to pull the string
  3196.     apart easily.
  3197.  
  3198. SetMachineWhisperOther: machine/character
  3199. proc utility SetMachineWhisperOther(thing machine; action theAction)action
  3200.  
  3201.     SetMachineWhisperOther sets, on the machine structure associated
  3202.     with 'machine', the action that will be called by the system
  3203.     whenever the machine "overhears" an agent whispering to another
  3204.     agent. The chance of the overhearing is controlled by the call to
  3205.     'Whisper' used. The action must have one string parameter and no
  3206.     result. The parameter will the the string whispered, preceeded by
  3207.     "<name1> whispers to <name2>:", where <name1> is the formatted
  3208.     name of the agent doing the whispering, and <name2> is the
  3209.     formatted name of who they are whispering to. The previous
  3210.     "whisperother action", if any, is returned. 'SetWhisperOther' can
  3211.     be used to pull apart the argument string.
  3212.  
  3213. SetMeString: utility
  3214. proc utility SetMeString(string name)void
  3215.  
  3216.     SetMeString sets the string that is used as the name of the active
  3217.     client when FindAgent is asked to find "self", "myself",
  3218.     "yourself" or "me". This string is set by the system to the name
  3219.     of the active client when any action is started on behalf of the
  3220.     client. Modifying the value is useful for some situations
  3221.     involving 'ForceAction'.
  3222.  
  3223. SetNewCharacterAction: machine/character
  3224. proc utility SetNewCharacterAction(action newAction)action
  3225.  
  3226.     SetNewCharacter sets the global action which is executed whenever
  3227.     a new character is initialized. This is done when a player first
  3228.     connects to that character in non-wizard mode, or when 'Normal' is
  3229.     first executed by the character. The old value of the
  3230.     "newcharacter action" is returned. This action will typically do
  3231.     things like initializing the character for properties that the
  3232.     scenario assumes all characters have, moving the character to the
  3233.     entry location, etc.
  3234.  
  3235. SetPrefix: utility
  3236. proc utility SetPrefix(string newPrefix)void
  3237.  
  3238.     SetPrefix sets a prefix which will be printed in front of output
  3239.     lines. The new prefix will appear before the next output line.
  3240.     Note that output lines can be caused by explicit newlines, or by
  3241.     the word wrapping of text that does not contain any newlines.
  3242.     There are three optional things that can be inserted at the front
  3243.     of output lines: an '@', a prefix, and an indent. They are
  3244.     inserted in that order. Note that any prefix is a very short-lived
  3245.     thing - it is cleared at the end of the current top-level call
  3246.     done by the server. They are not saved with the client structure,
  3247.     and are not saved on the character. Thus, code which desires a
  3248.     prefix in all or most places must set the prefix explicitly at the
  3249.     beginning of each handler call. See also: 'SetIndent'.
  3250.  
  3251. SetPrompt: utility
  3252. proc utility wizard SetPrompt(string prompt)string
  3253.  
  3254.     SetPrompt sets the prompt for the active client. The old prompt is
  3255.     returned. The default prompt is "input> ". Note that "wizard mode"
  3256.     has prompts of its own, not related to the character's prompt. The
  3257.     prompt will change immediately, unless there is currently a
  3258.     partial input line typed.
  3259.  
  3260. SetRemoteSysAdminOK: utility
  3261. proc utility SetRemoteSysAdminOK(bool state)void
  3262.  
  3263.     SetRemoteSysAdminOK sets whether or not the server will accept a
  3264.     login of SysAdmin via a remote connection. A connection via
  3265.     'MUDAgent' is always a remote connection, and a connection via
  3266.     'SMUD' is remote if the '-r' flag is given to 'SMUD'. The default
  3267.     is to not accept a remote SysAdmin connection, and it is highly
  3268.     recommended that you never change the setting. Doing so makes it
  3269.     possible for someone to learn or guess your SysAdmin password,
  3270.     which makes your entire system (not just AmigaMUD) wide open to
  3271.     that person.
  3272.  
  3273. SetSay: parsing
  3274. proc utility SetSay(string what)string
  3275.  
  3276.     SetSay is useful for interpreting a string passed to a machine
  3277.     "say action". It takes a string of the form "xxx says: yyy",
  3278.     returns "xxx" and puts "yyy" into the tail buffer, where it can be
  3279.     accessed with 'GetTail' and 'GetWord'.
  3280.  
  3281. SetSeed: utility
  3282. proc utility SetSeed(int newSeed)void
  3283.  
  3284.     SetSeed sets the seed for the server's random number generator.
  3285.     The value of the seed can be obtained via 'GetSeed'. Setting the
  3286.     seed allows for the generation of repeatable pseudo-random
  3287.     sequences, which can be used to reproduce a randomly generated
  3288.     area each time it is needed.
  3289.  
  3290. SetSingleUser: utility
  3291. proc utility SetSingleUser(bool state)void
  3292.  
  3293.     SetSingleUser sets a flag inside the database that controls
  3294.     whether the database represents a single-user "Adventure"-style
  3295.     game or a multi-user MUD. In single-user mode, the concept of
  3296.     "characters" does't really exist - when a client connects (only
  3297.     one is ever allowed at a time), no character name or password is
  3298.     required - the game goes right into handling user input. Note that
  3299.     because of the way MUDServ operates, the current state is always
  3300.     saved implicitly, and in order to make a saved position, the
  3301.     entire MUD database (MUD.data, MUD.index) must be backed up.
  3302.  
  3303. SetTail: parsing
  3304. proc utility SetTail(string str)void
  3305.  
  3306.     SetTail directly sets the value of the server's "tail" string.
  3307.     This string is set implicitly by a number of actions, including
  3308.     the parsing of a 'VerbTail' verb. The value of the string can be
  3309.     retrieved using 'GetTail', and individual words in it can be
  3310.     retrieved one at a time using 'GetWord'.
  3311.  
  3312. SetThingStatus: database
  3313. proc utility SetThingStatus(thing theThing; <thing status> status)void
  3314.  
  3315.     SetThingStatus sets the status of 'theThing' to 'status'. The
  3316.     "effective player" must own the thing, or the effective and real
  3317.     players must both be SysAdmin (i.e. SysAdmin is typing directly in
  3318.     wizard mode, or is running his own actions). The value of 'status'
  3319.     must be one of: 'ts_public', 'ts_private', 'ts_readonly', and
  3320.     'ts_wizard', as explained in previous documents.
  3321.  
  3322. SetWhisperMe: parsing
  3323. proc utility SetWhisperMe(string what)string
  3324.  
  3325.     SetWhisperMe is useful for interpreting a string passed to a
  3326.     machine "whisperme action". It takes a string of the form "xxx
  3327.     whispers: yyy", returns "xxx" and puts "yyy" into the tail buffer,
  3328.     where it can be accessed with 'GetTail' and 'GetWord'.
  3329.  
  3330. SetWhisperOther: parsing
  3331. proc utility SetWhisperOther(string what)string
  3332.  
  3333.     SetWhisperOther is useful for interpreting a string passed to a
  3334.     machine "whisperother action". It takes a string of the form "xxx
  3335.     whispers to yyy: zzz", returns "xxx" and puts "yyy zzz" into the
  3336.     tail buffer, where it can be accessed with 'GetTail' and
  3337.     'GetWord'.
  3338.  
  3339. ShowCharacter: utility
  3340. proc utility ShowCharacter(character who)void
  3341.  
  3342.     ShowCharacter prints to the active client the status of the
  3343.     indicated character. This includes the connection status, the
  3344.     character status (normal/apprentice/wizard), and an indication of
  3345.     whether or not the character is "new" (has executed the "newplayer
  3346.     action").
  3347.  
  3348. ShowCharacters: utility
  3349. proc utility ShowCharacters(bool longForm)int
  3350.  
  3351.     If 'longForm' is 'true', then ShowCharacters effectively calls
  3352.     'ShowCharacter' for each existing character. If 'longForm' is
  3353.     'false', then ShowCharacters prints just the names of all of the
  3354.     existing characters. Both lists are preceeded by "Existing
  3355.     characters as of " and the time and date. ShowCharacters returns
  3356.     the number of existing characters.
  3357.  
  3358. ShowClients: utility
  3359. proc utility ShowClients(bool longForm)int
  3360.  
  3361.     If 'longForm' is 'true' then ShowClients shows the name of all
  3362.     active clients, followed by their connection time and whether or
  3363.     not they are currently in "wizard mode". If 'longForm' is 'false',
  3364.     then ShowClients just shows the names of all active clients. Both
  3365.     forms are preceeded by "Active clients as of " and the current
  3366.     time and date. ShowClients returns the number of active clients.
  3367.  
  3368. ShowTable: symbols
  3369. proc utility ShowTable(table theTable)void
  3370.  
  3371.     ShowTable shows the symbols in the passed table. Only the names of
  3372.     the symbols are shown - 'DescribeSymbol' can be used to show the
  3373.     definition of a given symbol.
  3374.  
  3375. ShowWord: parsing
  3376. proc utility ShowWord(grammar theGrammar; string theWord)void
  3377.  
  3378.     ShowWord looks 'theWord' up in 'theGrammar' and prints, to the
  3379.     active client, the definition of that word. The output is one of:
  3380.  
  3381.     - not in grammar
  3382.     - code <n> {a separator word}
  3383.     - synonym of "xxx"
  3384.     - code <n> string tail verb => <action>
  3385.     - code <n> verb with alternatives:
  3386.         - no object
  3387.         - direct object
  3388.         - direct and indirect objects
  3389.         separator {<NONE> or "yyy"}
  3390.         => <action>
  3391.  
  3392. ShowWords: parsing
  3393. proc utility ShowWords(grammar theGrammar)void
  3394.  
  3395.     ShowWords prints, to the active client, the words in 'theGrammar'.
  3396.     The list is not sorted, but is in multiple columns. 'ShowWord' can
  3397.     be used to see the definition of a given word in the grammar.
  3398.  
  3399. ShutDown: utility
  3400. proc utility ShutDown(bool yesNo)bool
  3401.  
  3402.     ShutDown can be used by SysAdmin to set or clear the "shutdown
  3403.     flag". If this flag is set when the server reaches the state of
  3404.     having no clients, the server will shut itself down and exit.
  3405.  
  3406. SOn: effects
  3407. proc utility SOn(thing who)bool
  3408.  
  3409.     SOn returns 'true' if the indicated client ('who') has sound
  3410.     output enabled, and 'false' otherwise. A text-only client will
  3411.     always have all effects disabled.
  3412.  
  3413. SPlaySound: effects
  3414. proc utility SPlaySound(thing who; string name; int id)void
  3415.  
  3416.     SPlaySound instructs client 'who' to start playing an IFF 8SVX
  3417.     sound sample from "AmigaMUD:Sounds/<name>". The operation of the
  3418.     effect is given identifier 'id', and proceeds without the server
  3419.     or client waiting for it. When the sound is complete (or is
  3420.     aborted with 'AbortEffect'), the server will call the client's
  3421.     "effect done" action with parameters 0 and 'id'.
  3422.  
  3423. SPrint: output
  3424. proc utility SPrint(thing agent; string str)void
  3425.  
  3426.     SPrint prints string 'str' to client 'agent'. This is typically
  3427.     used when one character or machine is affecting another. As usual,
  3428.     the string will be word-wrapped into the client's display width.
  3429.  
  3430. StringReplace: utility
  3431. proc utility StringReplace(string s1; int pos; string s2)string
  3432.  
  3433.     StringReplace returns a string which is a copy of 's1', but with
  3434.     the characters starting at position 'pos' (zero origin) replaced
  3435.     by the characters of 's2'. If there is more of 's1' beyond the
  3436.     end of the 's2' replacement, it remains unchanged.
  3437.  
  3438. StringToAction: utility
  3439. proc utility StringToAction(string str)action
  3440.  
  3441.     StringToAction is one of the more powerful features of AmigaMUD.
  3442.     It takes a string, generated in whatever manner is needed, and
  3443.     attempts to parse and compile it into an action. The set of "in-
  3444.     use" tables controls the set of symbols that can be used, as
  3445.     usual. Any error messages generated as a result of the compilation
  3446.     will go to the active client (if any). If the compilation is
  3447.     successful, the newly created action is returned, else nil is
  3448.     returned. The standard scenario uses StringToAction to compile
  3449.     "builder actions" created by builders.
  3450.  
  3451. StringToInt: utility
  3452. proc utility StringToInt(string str)int
  3453.  
  3454.     StringToInt attempts to turn string 'str' into an integer value,
  3455.     which it returns. A leading '+' or '-' sign can be present. If the
  3456.     string cannot be decoded into a decimal integer, then a run-time
  3457.     error is generated. Note that 'StringToInt' simply stops at the
  3458.     first non-digit, as long as at least one digit is present.
  3459.  
  3460. StringToPosInt: utility
  3461. proc utility StringToPosInt(string str)int
  3462.  
  3463.     StringToPosInt is a safer alternative than 'StringToInt' for
  3464.     converting user input into an integer. It does not accept a '+' or
  3465.     '-' sign, but it will return -1 if the string it is passed does
  3466.     not start with a decimal digit.
  3467.  
  3468. Strip: utility
  3469. proc utility Strip(string st)string
  3470.  
  3471.     Strip will remove quotation marks (") from around a string and
  3472.     will expand escaped characters ('\n' and '\t') from the passed
  3473.     string, returning the processed result. The result is also left in
  3474.     the "tail buffer", where it can be accessed with 'GetWord'. If the
  3475.     string starts with a quotation mark, then that mark is stripped
  3476.     off, and any trailing mark is also stripped off, but internal
  3477.     marks are kept. If the first character of the string was not a
  3478.     quotation mark, then all marks are kept intact.
  3479.  
  3480. SubString: utility
  3481. proc utility SubString(string str; int start, length)string
  3482.  
  3483.     SubString returns a substring of 'str', starting at postion
  3484.     'start' (zero origin) for length 'length'. If 'start' + 'length'
  3485.     is greater than the length of 'str', then the resulting substring
  3486.     will be cut short. SubString will only abort execution if either
  3487.     'start' or 'length' is less than zero.
  3488.  
  3489. SVolume: effects
  3490. proc utility SVolume(thing who; int volume)void
  3491.  
  3492.     SVolume sets the sound playback volume in client 'who'. 'volume'
  3493.     is a value from 0 - 10000, with, e.g. 5000 representing half of
  3494.     the full volume.
  3495.  
  3496. Synonym: parsing
  3497. proc utility Synonym(grammar theGrammar; string oldWord, newWord)void
  3498.  
  3499.     Synonym defines a synonym in 'theGrammar'. 'oldWord' is looked up
  3500.     in the grammar, and must be found, else a run-time error is
  3501.     produced. 'newWord', which must not exist in the grammar, is made
  3502.     to be a synonym of that word. Note that you cannot make a synonym
  3503.     of a synomym - you must make another synonym of the original word
  3504.     instead.
  3505.  
  3506. TextHeight: output
  3507. proc utility wizard TextHeight(int newHeight)int
  3508.  
  3509.     TextHeight sets the active client's text output height to
  3510.     'newHeight' lines of text, returning the old value. A client using
  3511.     the Amiga "MUD" program has the text height set to the height of
  3512.     the full text window, which will vary depending on overscan and
  3513.     PAL versus NTSC. For other clients, the default height is 23
  3514.     lines. The number of lines is useful for code which wants to
  3515.     paginate output, such as the email and news readers in the
  3516.     standard scenario. As a special case, if the passed height is 0,
  3517.     then the height is not changed, but is still returned.
  3518.  
  3519. TextWidth: output
  3520. proc utility wizard TextWidth(int newWidth)int
  3521.  
  3522.     TextWidth sets the active client's text output width to 'newWidth'
  3523.     columns, returning the old value. A client using the Amiga "MUD"
  3524.     program has the text width set to the width of the text window,
  3525.     which will vary depending on overscan. For other clients, the
  3526.     default width is 78 characters. The text output width is the width
  3527.     to which the server's output code will wrap output text going to
  3528.     the client. Note that the Amiga "MUD" client program will also
  3529.     wrap output text to its actual text window width, so making the
  3530.     client's text width value too large makes a real mess. As a
  3531.     special case, if the passed width is 0, then the width is not
  3532.     changed, but is still returned.
  3533.  
  3534. ThingCharacter: machine/character
  3535. proc utility ThingCharacter(thing theThing)character
  3536.  
  3537.     ThingCharacter returns the character associated with 'theThing',
  3538.     if there is one. If there isn't one, then nil is returned. The
  3539.     opposite conversion, from character to thing, is done by
  3540.     'CharacterThing'. Note that 'ThingCharacter' will only find an
  3541.     active client - it does not check inactive characters.
  3542.  
  3543. Time: utility
  3544. proc utility Time()int
  3545.  
  3546.     Time returns the current time in seconds, from some arbitrary
  3547.     start point, as an integer. This is useful for comparing when
  3548.     events happen, by storing the time value as the event happens.
  3549.  
  3550. Trace: utility
  3551. proc utility wizard Trace(int n)void
  3552.  
  3553.     Trace will add an entry to the server's trace buffer, titled "user
  3554.     trace", and with numerical value 'n'. This trace buffer is a
  3555.     circular buffer, currently of size 100 entries (although this may
  3556.     change in the future), in which the server records a history of
  3557.     recent events. This trace buffer is dumped out, latest event to
  3558.     earliest event, if the server aborts. The entire trace facility
  3559.     may be compiled out of the server in some future release.
  3560.  
  3561. Trim: utility
  3562. proc utility Trim(string str)string
  3563.  
  3564.     Trim returns a copy of its argument string, but with any leading
  3565.     and trailing spaces removed. Internal spaces are not altered.
  3566.  
  3567. TrueMe: utility
  3568. proc utility TrueMe()thing
  3569.  
  3570.     TrueMe returns the identity of the original character or machine
  3571.     for this execution. The use of 'ForceAction' will not change the
  3572.     value returned, unlike that returned from 'Me'. The standard
  3573.     scenario uses TrueMe from some of the Packrat code, to determine
  3574.     the identity of the player who instructs her to do something.
  3575.  
  3576. UnUseTable: symbols
  3577. proc utility UnUseTable(table theTable)bool
  3578.  
  3579.     UnUseTable removes 'theTable' from the set of "in-use" tables.
  3580.     Symbols defined in that table, and not in any other in-use table,
  3581.     will no longer be available for use when compiling. This is the
  3582.     same as the "unuse" command in wizard mode.
  3583.  
  3584. UseTable: symbols
  3585. proc utility UseTable(table theTable)bool
  3586.  
  3587.     UseTable adds 'theTable' to the set of "in-use" tables. Symbols in
  3588.     the table will now be available for use when compiling. This is
  3589.     the same as the "use" command in wizard mode.
  3590.  
  3591. Verb: parsing
  3592. proc utility Verb()string
  3593.  
  3594.     Verb returns the string which the user entered as the verb for the
  3595.     current command. In the presence of synonyms for a verb, this
  3596.     allows the scenario code to know which form of a verb the user
  3597.     typed. This can be useful when making minor distinctions of
  3598.     meaning or usage.
  3599.  
  3600. Verb0: parsing
  3601. proc utility Verb0(grammar theGrammar; string theVerb; int separatorCode;
  3602.     action theAction)void
  3603.  
  3604.     Verb0 enters string 'theVerb' into grammer 'theGrammar' as a verb
  3605.     which takes no (0) objects (in the English language sense). If
  3606.     'separatorCode' is nonzero, then it is the code for a word which
  3607.     can be given with this verb in order to distinguish it from other
  3608.     possible uses of the same word as a verb. The AmigaMUD parser will
  3609.     call action 'theAction' with no parameters when it parses this
  3610.     verb/separator combination. The action should return a boolean
  3611.     value, with 'false' indicating that something has gone wrong, and
  3612.     any remaining commands on the input line should not be processed.
  3613.     Some examples:
  3614.  
  3615.     private proc goNorth()bool:
  3616.         if Here()@p_rNorth = nil then
  3617.         Print("You can't go that way.\n");
  3618.         false
  3619.         else
  3620.         SetLocation(Here()@p_rNorth);
  3621.         true
  3622.         fi
  3623.     corp;
  3624.     Verb0(G, "north", 0, goNorth).
  3625.     Synonym(G, "north", "n").
  3626.  
  3627.     private proc sitUp()bool:
  3628.         ...
  3629.     corp;
  3630.     Verb0(G, "sit", FindWord(G, "up"), sitUp).
  3631.  
  3632. Verb1: parsing
  3633. proc utility Verb1(grammar theGrammar; string theVerb; int separatorCode;
  3634.     action theAction)void
  3635.  
  3636.     Verb1 adds to grammar 'theGrammar' verb 'theVerb' which expects a
  3637.     direct object when it is used. 'separatorCode', if not zero, is a
  3638.     word which can be between the verb and its direct object noun-
  3639.     phrase, or after the noun-phrase. The AmigaMUD parser will
  3640.     automatically handle multiple noun phrases, separated by commas or
  3641.     "and"s, and will pass them, in internal "noun;adj,adj,..." form,
  3642.     in turn to action 'theAction'. The action should return a bool,
  3643.     with 'false' indicating that some error has occurred, and no more
  3644.     calls to it should be made for this command, and that no more
  3645.     commands from the current input line should be processed. It is
  3646.     possible for 'theAction' to be called with an empty string if the
  3647.     verb is used by itself, and no object-less variant of that verb
  3648.     exists. Examples:
  3649.  
  3650.     private proc pickUp(string what)bool:
  3651.         status st;
  3652.         thing th;
  3653.  
  3654.         if what = "" then
  3655.         Print("Pick up what?\n");
  3656.         false
  3657.         else
  3658.         st := FindName(Here()@p_rContents, what);
  3659.         if st = continue then
  3660.             Print(FormatName(what) + " is ambiguous.\n");
  3661.             false
  3662.         elif st = fail then
  3663.             Print("There is no " + FormatName(what) + " here.\n");
  3664.             false
  3665.         else
  3666.             th := FindResult();
  3667.             AddTail(Me()@p_pCarrying, th);
  3668.             DelElement(Here()@p_rContents, th);
  3669.             Print(FormatName(what) + " picked up.\n");
  3670.             true
  3671.         fi
  3672.         fi
  3673.     corp;
  3674.     Verb1(G, "pick", FindWord(G, "up"), pickUp).
  3675.     Verb1(G, "take", 0, pickUp).
  3676.  
  3677.     Note that it is important to do the 'AddTail' before the
  3678.     'DelElement', so that if there are no other references to the
  3679.     objec,t it doesn't get deleted by the database code. Assume the
  3680.     player is in a room containing:
  3681.  
  3682.     small whisk broom
  3683.     straw broom
  3684.     pewter mug
  3685.     brass bell
  3686.     large red ball
  3687.  
  3688.     then, the following commands should produce:
  3689.  
  3690.     pick up the pewter mug
  3691.         -> pewter mug picked up.
  3692.     pick the basket up.
  3693.         -> There is no basket here.
  3694.     take
  3695.         -> Pick up what?
  3696.     Pick the broom up.
  3697.         -> broom is ambiguous.
  3698.     Take small broom, straw broom and the large red ball.
  3699.         -> small whisk broom picked up.
  3700.         -> straw broom picked up.
  3701.         -> large red ball picked up.
  3702.     Pick the brass bell and mug up.
  3703.         -> brass bell picked up.
  3704.         -> pewter mug picked up.
  3705.  
  3706. Verb2: parsing
  3707. proc utility Verb2(grammar theGrammar; string theVerb; int separatorCode;
  3708.     action theAction)void
  3709.  
  3710.     Verb2 adds to 'theGrammar' verb 'theVerb' as a verb which takes
  3711.     both a direct object and an indirect object. 'separatorCode' must
  3712.     be nonzero, and the word it is the code for (or a synonym) must be
  3713.     present in an input command that matches the verb. The separator
  3714.     word separates the direct object noun-phrase from the indirect
  3715.     object noun-phrase, as in "Put the marble INTO the bag.".
  3716.     'theAction' is an action which the parser will call to handle the
  3717.     verb. It will be passed two strings - the internal form of the
  3718.     direct object, and the internal form of the indirect object. The
  3719.     AmigaMUD parser will automatically handle input commands with
  3720.     multiple direct objects, separated by commas or "and"s and will
  3721.     call the action sequentially with them and the single indirect
  3722.     object. If no objects of either kind are given, the parser will
  3723.     complain with "<verb> who/what <separator> who/what?". If a direct
  3724.     object is given, but no indirect object, then the complaint will
  3725.     be of the form "<verb> <direct object> <separator> who/what?". If
  3726.     an indirect object but no direct object is given, then the parser
  3727.     will complain "<verb> who/what <separator> <indirect object>?".
  3728.     Thus, a Verb2 handler does not have to worry about handling empty
  3729.     strings. The handler returns a bool value, with 'false' indicating
  3730.     that something has gone wrong, and the parser should not call it
  3731.     for any further objects in this command, and any further commands
  3732.     in the current input line should also be cancelled. An example:
  3733.  
  3734.     private proc doPutIn(string itemRaw, containerRaw)bool:
  3735.     thing item, container;
  3736.     string itemName, containerName;
  3737.     status st;
  3738.  
  3739.     itemName := FormatName(itemRaw);
  3740.     containerName := FormatName(containerRaw);
  3741.     st := MatchName(Me()@p_pCarrying, itemRaw);
  3742.     if st = continue then
  3743.         Print(Capitalize(itemName) + " is ambiguous.\n");
  3744.         false
  3745.     elif st = fail then
  3746.         Print("You have no " + itemName + ".\n");
  3747.         false
  3748.     else
  3749.         item := FindResult();
  3750.         st := FindName(Me()@p_pCarrying, containerRaw);
  3751.         if st = continue then
  3752.         Print(Capitalize(containerName) + " is ambiguous.\n");
  3753.         false
  3754.         elif st = fail then
  3755.         Print("You have no " + containerName + ".\n");
  3756.         false
  3757.         else
  3758.         container := FindResult();
  3759.         if container@p_oContents = nil then
  3760.             Print("You can't put things into the " +
  3761.             containerName + ".\n");
  3762.             false
  3763.         else
  3764.             AddTail(container@p_oContents, item);
  3765.             DelElement(Me()@p_pCarrying, item);
  3766.             Print("You put the " + itemName + " into the " +
  3767.             containerName + ".\n");
  3768.             true
  3769.         fi
  3770.         fi
  3771.     fi
  3772.     corp;
  3773.     Verb2(G, "put", FindWord(G, "in"), doPutIn).
  3774.     Verb2(G, "put", FindWord(G, "into"), doPutIn).
  3775.     Synonym(G, "put", "place").
  3776.  
  3777.     Assume the player is carrying:
  3778.  
  3779.     small whisk broom
  3780.     straw broom
  3781.     pewter mug
  3782.     brass bell
  3783.     large red ball
  3784.     canvas sack
  3785.  
  3786.     then, the following commands should produce:
  3787.  
  3788.     put mug in sack
  3789.         -> You put the pewter mug into the canvas sack.
  3790.     Place the large red ball into the brass bell.
  3791.         -> You can't put things into the brass bell.
  3792.     put broom in sack
  3793.         -> Broom is ambiguous.
  3794.     place the bell into broom
  3795.         -> Broom is ambiguous.
  3796.     put bell, ball and whisk broom into sack
  3797.         -> You put the brass bell into the canvas sack.
  3798.         -> You put the large red ball into the canvas sack.
  3799.         -> You put the small whisk broom into the canvas sack.
  3800.  
  3801. VerbTail: parsing
  3802. proc utility VerbTail(grammar theGrammar; string theVerb;
  3803.     action theAction)void
  3804.  
  3805.     VerbTail adds verb 'theVerb' to grammar 'theGrammar' as a verb
  3806.     which is simply given the rest of the command to interpret as it
  3807.     sees fit. 'theAction' must have no parameters and return a bool
  3808.     result, with 'false' meaning that any further commands in the
  3809.     current input line should be skipped. When 'theAction' is called,
  3810.     the rest of the command will be in the "tail buffer", where it can
  3811.     be accessed using 'GetWord' and 'GetTail'. VerbTail verbs are used
  3812.     to handle verb forms which do not fit into the Verb0, Verb1 or
  3813.     Verb2 formats. The standard scenario uses VerbTail forms for many
  3814.     of the building commands (and the build command itself), since
  3815.     their formats do not involve noun-phrases at all. An example:
  3816.  
  3817.     private proc doTell()bool:
  3818.         string name, word;
  3819.         thing who;
  3820.  
  3821.         name := GetWord();
  3822.         if name = "" then
  3823.         Print("Tell who to what?\n");
  3824.         false
  3825.         else
  3826.         who := FindAgent(name);
  3827.         if who = nil then
  3828.             Print("There is no-one here by that name.\n");
  3829.             false
  3830.         else
  3831.             word := GetWord();
  3832.             if word == "to" then
  3833.             Say(name + "," + GetTail());
  3834.             else
  3835.             Say(name + "," + word + " " + GetTail());
  3836.             fi;
  3837.             true
  3838.         fi
  3839.         fi
  3840.     corp;
  3841.     VerbTail(G, "tell", doTell).
  3842.     Synonym(G, "tell", "instruct").
  3843.  
  3844.     This makes the form "tell xxx [to] yyy" an alternate way to try to
  3845.     speak commands to others in the room. The following inputs could
  3846.     result in the given spoken output or complaints:
  3847.  
  3848.     tell SysAdmin to go away
  3849.         -> "SysAdmin, go away
  3850.     tell
  3851.         -> Tell who to what?
  3852.     tell Furklewitz to snybuld the whulsyp.
  3853.         -> There is no-one here by that name.
  3854.     Instruct SysAdmin go north.
  3855.         -> "SysAdmin, go north
  3856.  
  3857. VNarrate: effects
  3858. proc utility VNarrate(thing who; string phonemes; int id)void
  3859.  
  3860.     VNarrate instructs the specified client to use its narrator.device
  3861.     to speak the given phoneme sequence. If that client doesn't have
  3862.     the device, then nothing happens except a small error comment in
  3863.     the client's text window. This will only happen if the client has
  3864.     voice output enabled, however. 'id' is supplied as an identifier
  3865.     for this effect. When the effect completes, or is aborted, the
  3866.     system will call the character's "effects done" action, if any,
  3867.     passing it the values 1 and 'id'. See the Amiga manuals for a
  3868.     description of the format of a phoneme sequence. Phoneme sequences
  3869.     can be produced by using the 'VTranslate' builtin, provided the
  3870.     server is running on a system containing 'translator.library' in
  3871.     its LIBS: directory. For example:
  3872.  
  3873.     define tp_mall proc bankSay()status:
  3874.         if VOn(nil) then
  3875.         VParams(nil, 150, 120, 0, 0, 64);
  3876.         VNarrate(nil,
  3877.             "WEH5LKAHM KAH4STAHMER. DIH4PAAZIHT MAH4NIY TUWDEY1.",
  3878.             BANK_SPEECH_ID);
  3879.         VReset(nil);
  3880.         fi;
  3881.         continue
  3882.     corp;
  3883.  
  3884. VOn: effects
  3885. proc utility VOn(thing who)bool
  3886.  
  3887.     VOn returns 'true' if the specified client can accept voice
  3888.     output, and that feature has not been disabled by the user. Note
  3889.     that the presence of 'narrator.device' is NOT checked.
  3890.  
  3891. VParams: effects
  3892. proc utility VParams(thing who; int rate, pitch, mode, sex, volume)void
  3893.  
  3894.     VParams sets the parameters for voice output on the specified
  3895.     client. These parameters are only the old, pre 2.0 'narrator.
  3896.     device' parameters, and are:
  3897.  
  3898.     rate - the speed of the speech, default 150
  3899.     pitch - the pitch of the speech, default 110
  3900.     mode - the mode (natural = 0, robotic = 1), default natural
  3901.     sex - the speaker sex (male = 0, female = 1), default male
  3902.     volume - the volume of the speech, with 64 being full volume
  3903.  
  3904. VReset: effects
  3905. proc utility VReset(thing who)void
  3906.  
  3907.     VReset instructs the specified client to reset its voice
  3908.     parameters to the specified values. See 'VParams' for those
  3909.     values.
  3910.  
  3911. VSpeak: effects
  3912. proc utility VSpeak(thing who; string words; int id)void
  3913.  
  3914.     VSpeak instructs the specified client to speak the given English
  3915.     text. The text is translated to phonemes in the server, and will
  3916.     thus fail if the server does not have "LIBS:translator.library".
  3917.     The speaking is given effects identifier 'id', and the system will
  3918.     arrange to call the character's "effects done" action with
  3919.     parameters 1 and 'id' when it completes or is aborted. No speech
  3920.     will be produced if the client does not have "narrator.device"
  3921.     available. Example:
  3922.  
  3923.     VSpeak(CharacterThing(Character("SysAdmin")),
  3924.         "Hey wimp! Your mother wears army boots!", 0).
  3925.  
  3926. VTranslate: effects
  3927. proc utility VTranslate(string words)string
  3928.  
  3929.     VTranslate translates English text string 'words' into a phoneme
  3930.     sequence, which it returns. If the server does not have access to
  3931.     "LIBS:translator.library", then an empty string is returned.
  3932.     Output phoneme sequences are restricted to 999 characters.
  3933.  
  3934. VVolume: effects
  3935. proc utility VVolume(thing who; int volume)void
  3936.  
  3937.     VVolume sets the overall speech volume for the given client. A
  3938.     value of 10000 is full volume, 5000 is half volume, etc. This
  3939.     value is a long-term value, and is used to scale any individual
  3940.     volume set via 'VParams'.
  3941.  
  3942. Whisper: machine/character
  3943. proc utility Whisper(string alternateName, what; thing who;
  3944.     int percent)bool
  3945.  
  3946.     Whisper is used to attempt to whisper to a specific other agent in
  3947.     the same room as the active one. 'what' is what is to be
  3948.     whispered, 'who' is who to whisper it to, and 'percent' is the
  3949.     likelihood that any other agent in the room will overhear the
  3950.     whisper (evaluated once for each other agent in the room). If
  3951.     'who' is a player, they will see: "<name> whispers: <what>", where
  3952.     <name> is either 'alternateName', or the name of the active agent
  3953.     if 'alternateName' is an empty string. If 'who' is a machine, then
  3954.     that machine's "whisperme action", if any, is called with a string
  3955.     of the same format. If 'percent' is greater than zero then each
  3956.     other character or machine in the same room may overhear the
  3957.     whisper ('percent' = 50 gives a 50 percent chance, etc.). Players
  3958.     will see a message of the form "<name> whispers to <who-name>: <
  3959.     what>". Machines will have their "whisperother action", if any,
  3960.     called with a string of that form. For example, if player "Fred"
  3961.     whispers to player "Joe" the string "help me kill sam", then Joe
  3962.     will see:
  3963.  
  3964.     Fred whispers: help me kill sam
  3965.  
  3966.     and any overhearer will see:
  3967.  
  3968.     Fred whispers to Joe: help me kill sam
  3969.  
  3970. WhoName: parsing
  3971. proc utility WhoName()string
  3972.  
  3973.     WhoName returns the internal form of the indirect object given by
  3974.     the user for a Verb2 verb. This can be used for special checks for
  3975.     particular adjectives, etc. See also: 'ItName'.
  3976.  
  3977. WizardMode: utility
  3978. proc utility WizardMode()bool
  3979.  
  3980.     WizardMode attempts to put the active client into "wizard mode",
  3981.     where input lines go directly to the AmigaMUD programming language
  3982.     parser, rather than to the character's "input action". The attempt
  3983.     will fail (silently) if the active agent is a machine, or if the
  3984.     active client is not enabled for wizarding (has status normal), or
  3985.     if the client program in use is not capable of going into wizard
  3986.     mode. There currently aren't any such client programs, but it is
  3987.     easier to produce a client for a machine other than the Amiga if
  3988.     the wizard-mode stuff (programming language parsing, etc.) can be
  3989.     left out.
  3990.  
  3991. Word: parsing
  3992. proc utility Word(grammar theGrammar; string theWord)int
  3993.  
  3994.     Word adds word 'theWord' to grammar 'theGrammar'. The word is not
  3995.     a verb, but is available for use as a "separator word" with a
  3996.     verb, or for whatever other use is needed. The identifying code
  3997.     for the word is returned. If the word cannot be added to the
  3998.     grammar, then 0 is returned.
  3999.